{"id":"@lssm-tech/app.api-application-monolith","slug":"app.api-application-monolith","name":"@lssm-tech/app.api-application-monolith","version":"12.0.1","path":"packages/apps/api-application-monolith","manifestPath":"packages/apps/api-application-monolith/package.json","manifestBlobSha":"df905c0adceab76e4a35d3900e8a2ab2506dbe7a","layer":"apps","physicalArea":null,"primaryArea":"app-composition","classification":{"privateDeclared":true,"catalogFamily":null,"catalogKind":null,"catalogStatus":null,"adoptionMode":null,"stability":null},"description":null,"descriptionOrigin":"package.json","catalog":{},"canonicalImports":[],"scripts":{"clean":"rm -rf dist api/dist .turbo","build":"bun run build:elysia","build:identity":"mkdir -p ../../../api/dist && bun build --target node --packages bundle --outfile ../../../api/dist/identity-index.js src/identity-app.ts","build:lssm-os":"mkdir -p ../../../api/dist && bun build --target node --packages bundle --outfile ../../../api/dist/lssm-os-index.js src/lssm-os-app.ts","dev":"bun run dev:elysia","start":"bun run start:elysia","build:elysia":"bun build --target node --packages bundle --external '@google-cloud/storage' --external '@elevenlabs/elevenlabs-js' --external '@fal-ai/client' --external '@composio/core' --external 'loro-crdt' --outfile dist/index.js src/app.ts && mkdir -p api/dist/node_modules/loro-crdt && cp dist/index.js api/dist/index.js && cp node_modules/loro-crdt/package.json api/dist/node_modules/loro-crdt/package.json && cp -R node_modules/loro-crdt/nodejs api/dist/node_modules/loro-crdt/nodejs && cp -R node_modules/loro-crdt/base64 api/dist/node_modules/loro-crdt/base64 && cp src/runtime/loro-base64-package.json api/dist/node_modules/loro-crdt/base64/package.json","start:elysia":"bun run ./server.mjs","dev:elysia":"bun run --watch src/app.ts","lint":"bun run lint:fix","lint:fix":"node ../../../scripts/biome.cjs check --write --unsafe --only=nursery/useSortedClasses . && node ../../../scripts/biome.cjs check --write .","lint:check":"node ../../../scripts/biome.cjs check .","test":"bun test","typecheck":"bun run typecheck:build && bun run typecheck:scripts","typecheck:build":"bun --bun x tsgo --project tsconfig.build.json --noEmit","typecheck:scripts":"bun --bun x tsgo --project tsconfig.scripts.json --noEmit","companyos:db:migrate:test":"bun src/db/local-test-lifecycle.ts migrate","companyos:db:seed:test":"bun src/db/local-test-lifecycle.ts seed","companyos:db:verify:test":"bun src/db/local-test-lifecycle.ts verify","companyos:db:reset:test":"bun src/db/local-test-lifecycle.ts reset","companyos:db:prove-rls:test":"bun src/db/rls-proof.ts","companyos:briefings:postgres:test":"bun test src/db/calendar-intelligence-postgres.integration.test.ts","companyos:db:prove-disposable-postgres":"bash scripts/companyos-disposable-postgres-proof.sh","companyos:db:prove-existing-postgres":"bash scripts/companyos-existing-postgres-proof.sh","companyos:db:company-intelligence:test":"bun test src/company-intelligence/repositories/company-intelligence-postgres.integration.test.ts && bun test src/company-intelligence/ingestion/continuous-ingestion-postgres.integration.test.ts && bun test src/company-intelligence/ingestion/continuous-ingestion-receipts-postgres.integration.test.ts","test:company-intelligence:persistence":"bun run companyos:db:company-intelligence:test && bun test src/company-intelligence/repositories/structured-extraction-postgres.integration.test.ts","test:company-intelligence:governed-learning-persistence":"bun test src/company-intelligence/learning/governed-learning-repository.test.ts src/company-intelligence/learning/governed-learning-repository-postgres.integration.test.ts","test:company-intelligence:ingestion":"bun run --cwd ../../domains/company/runtime test:company-intelligence:ingestion && bun test src/company-intelligence/ingestion/ingestion-idempotency-parity.test.ts","test:company-intelligence:graph-repository":"bun test src/company-intelligence/graph/graph-repository.test.ts src/company-intelligence/graph/graph-repository-regression.test.ts src/company-intelligence/graph/graph-repository-postgres.integration.test.ts","test:company-intelligence:brain":"bun test src/company-intelligence/brain/brain-repository.test.ts src/company-intelligence/brain/brain-projection.test.ts","test:company-intelligence:api":"bun test src/company-intelligence/api/api-contract.test.ts src/company-intelligence/api/api-state-migration.test.ts src/company-intelligence/api/api-state-postgres.test.ts src/company-intelligence/api/api-postgres-orchestrator.test.ts src/company-intelligence/api/api-postgres-operations.test.ts src/company-intelligence/api/api-postgres-authorization.test.ts src/company-intelligence/api/api-local-authorization.test.ts src/company-intelligence/api/api-governed-learning-postgres.test.ts src/handlers/companyos/company-intelligence-handler.test.ts src/handlers/companyos/company-intelligence-durable-controls.test.ts src/handlers/companyos/company-intelligence-negative.test.ts","test:company-intelligence:api:negative":"CI_SCENARIO=auth bun test src/handlers/companyos/company-intelligence-negative.test.ts && CI_SCENARIO=limits bun test src/handlers/companyos/company-intelligence-negative.test.ts && CI_SCENARIO=outages bun test src/handlers/companyos/company-intelligence-negative.test.ts","billing:db:migrate:test":"bun src/db/billing/local-test-lifecycle.ts migrate","billing:db:reset:test":"bun src/db/billing/local-test-lifecycle.ts reset","billing:db:prove-rls:test":"bun src/db/billing/rls-proof.ts","companyos:bootstrap-admin":"bun scripts/bootstrap-admin.ts","companyos:booking-surfaces:activate":"bun scripts/activate-booking-surfaces.ts","companyos:opa:reconcile-meeting-authority":"bun scripts/reconcile-opa-meeting-authority.ts","companyos:authority:repair-jsonb":"bun scripts/repair-authority-jsonb.ts","companyos:jsonb:normalize-text":"bun scripts/normalize-json-text.ts","companyos:opa:backfill-work-planning":"bun scripts/backfill-work-planning-enrollment.ts","companyos:opa:reset-canonical":"bun scripts/reset-canonical-opa-surfaces.ts","companyos:auth:rotate-admin-password":"bun scripts/rotate-admin-password.ts","companyos:auth:close-accounts":"bun scripts/close-accounts.ts","companyos:org:decommission":"bun scripts/decommission-organization.ts","companyos:sso:mock-idp":"bun scripts/sso-mock-idp.ts","prebuild":"bun --bun x tsgo --project tsconfig.build.json --noEmit","companyos:builder:db:migrate:test":"bun run companyos:db:migrate:test","companyos:builder:db:seed":"bun run companyos:db:seed:test","companyos:builder:db:verify":"bun run companyos:db:verify:test","companyos:builder:db:prove-rls":"bun run companyos:db:prove-rls:test","companyos:builder:api-smoke":"bun test src/handlers/builder/builder-public-handler.test.ts","companyos:builder:webhook-smoke":"bun test src/handlers/builder/builder-public-handler.test.ts","companyos:builder:provider-smoke":"bun test src/handlers/builder/builder-public-handler.test.ts","companyos:db:migrate:live":"bun scripts/companyos-live-db.ts migrate","companyos:db:opa-v2-activation":"bun scripts/opa-v2-owner-activation.ts","companyos:db:seed:live":"bun scripts/companyos-live-db.ts seed","companyos:db:verify:live":"bun scripts/companyos-live-db.ts verify","companyos:db:test:live-safety":"bun test src/db/live-safe-lifecycle.test.ts src/db/local-test-lifecycle.test.ts","profile-seo:postgres-conformance":"bun scripts/profile-seo-postgres-conformance.ts"},"scriptStatus":"complete pinned manifest","dependencies":{"@better-auth/drizzle-adapter":"1.7.5","@lssm-tech/bundle.library":"workspace:*","@lssm-tech/bundle.managed-companyos":"workspace:*","@lssm-tech/bundle.workspace":"workspace:*","@lssm-tech/integration.authos-better-auth":"workspace:*","@lssm-tech/integration.communication-os-host-auth":"workspace:*","@lssm-tech/integration.builder-telegram":"workspace:*","@lssm-tech/integration.builder-whatsapp":"workspace:*","@lssm-tech/integration.communication-os-persistence":"workspace:*","@lssm-tech/integration.communication-os-runtime":"workspace:*","@lssm-tech/integration.crdt-loro":"workspace:*","@lssm-tech/integration.governed-data-postgres":"workspace:*","@lssm-tech/integration.governed-product-data-postgres":"workspace:*","@lssm-tech/integration.opa-calendar-bridge":"workspace:*","@lssm-tech/integration.opa-meeting-context-bridge":"workspace:*","@lssm-tech/integration.opa-notification-bridge":"workspace:*","@lssm-tech/integration.provider-database":"workspace:*","@lssm-tech/integration.provider-calendar":"workspace:*","@lssm-tech/integration.provider-codex":"workspace:*","@lssm-tech/integration.provider-einvoicing":"workspace:*","@lssm-tech/integration.provider-email":"workspace:*","@lssm-tech/integration.provider-llm":"workspace:*","@lssm-tech/integration.provider-voice":"workspace:*","@lssm-tech/integration.provider-meeting-recorder":"workspace:*","@lssm-tech/integration.provider-messaging":"workspace:*","@lssm-tech/integration.provider-sms":"workspace:*","@lssm-tech/integration.runtime":"workspace:*","@lssm-tech/integration.runtime-managed":"workspace:*","@lssm-tech/integration.work-durable-store":"workspace:*","@lssm-tech/lib.authos-runtime":"workspace:*","@lssm-tech/lib.authos-spec":"workspace:*","@lssm-tech/lib.billing-france":"workspace:*","@lssm-tech/lib.billing-runtime":"workspace:*","@lssm-tech/lib.builder-spec":"workspace:*","@lssm-tech/lib.billing-spec":"workspace:*","@lssm-tech/lib.builder-runtime":"workspace:*","@lssm-tech/lib.communication-runtime":"workspace:*","@lssm-tech/lib.communication-spec":"workspace:*","@lssm-tech/lib.companyos-runtime":"workspace:*","@lssm-tech/lib.companyos-spec":"workspace:*","@lssm-tech/lib.contracts-integrations":"workspace:*","@lssm-tech/lib.contracts-runtime-server-rest":"workspace:*","@lssm-tech/lib.contracts-spec":"workspace:*","@lssm-tech/lib.data-exchange-core":"workspace:*","@lssm-tech/lib.data-exchange-server":"workspace:*","@lssm-tech/lib.design-catalog":"workspace:*","@lssm-tech/lib.identity-rbac":"workspace:*","@lssm-tech/lib.jobs":"workspace:*","@lssm-tech/lib.notification":"workspace:*","@lssm-tech/lib.observability":"workspace:*","@lssm-tech/lib.organization-planning-runtime":"workspace:*","@lssm-tech/lib.organization-planning-spec":"workspace:*","@lssm-tech/lib.personalization":"workspace:*","@lssm-tech/lib.provider-spec":"workspace:^","@lssm-tech/lib.work-runtime":"workspace:*","@lssm-tech/lib.work-spec":"workspace:*","@lssm-tech/module.auth-os":"workspace:*","@lssm-tech/module.billing-os":"workspace:*","@lssm-tech/module.company-metrics":"workspace:*","@lssm-tech/module.design-studio":"workspace:*","@lssm-tech/module.forms":"workspace:*","@lssm-tech/module.work-management":"workspace:*","@opentelemetry/api":"^1.9.1","@opentelemetry/sdk-trace-base":"^2.10.0","@vercel/functions":"^3.9.5","drizzle-orm":"catalog:data","elysia":"catalog:server","googleapis":"catalog:integrations","loro-crdt":"^1.16.1","next":"catalog:","pg":"catalog:server","postgres":"^3.4.9","posthog-node":"^5.51.7","react":"catalog:","react-dom":"catalog:","twilio":"catalog:integrations","zod":"catalog:","better-auth":"1.7.5","@lssm-tech/lib.knowledge":"workspace:*","@lssm-tech/lib.ai-providers":"workspace:*","@lssm-tech/integration.provider-storage":"workspace:*","ai":"catalog:ai","@aws-sdk/client-s3":"^3.1135.0","@lssm-tech/integration.lssm-os-state-sqlite":"workspace:^","@lssm-tech/lib.contractspec-connect":"workspace:^","@lssm-tech/lib.lssm-os-runtime":"workspace:^","@lssm-tech/lib.lssm-os-spec":"workspace:^","@lssm-tech/module.lssm-os-control-plane":"workspace:^","@lssm-tech/integration.osint-managed-runtime":"workspace:*","@lssm-tech/integration.osint-store":"workspace:*","@lssm-tech/integration.provider-embedding":"workspace:*","@lssm-tech/integration.provider-vector-store":"workspace:*","@lssm-tech/integration.meeting-intake-worker-postgres-http":"workspace:^","@lssm-tech/integration.company-intelligence-postgres":"workspace:*","@lssm-tech/integration.communication-channel-email":"workspace:*","@lssm-tech/lib.founder-intelligence-spec":"workspace:*"},"devDependencies":{"@lssm-tech/tool.typescript":"workspace:*","drizzle-kit":"catalog:data","typescript":"catalog:","@types/node":"catalog:types","@types/react":"catalog:types","@types/react-dom":"catalog:types","@electric-sql/pglite":"catalog:data","@types/pg":"catalog:types","@peculiar/x509":"1.14.3","xml-crypto":"6.3.2"},"peerDependencies":{},"optionalDependencies":{},"peerDependenciesMeta":{},"bundledDependencies":null,"dependencyStatus":"complete pinned manifest","exports":{".":"./src/index.ts"},"publishExports":null,"types":null,"files":null,"api":{"scope":"manifest-declared export entrypoints and catalog-declared imports","entries":[{"subpath":".","importPath":"@lssm-tech/app.api-application-monolith","target":"./src/index.ts","targets":[{"conditions":[],"target":"./src/index.ts","sourcePath":"packages/apps/api-application-monolith/src/index.ts","sourceUrl":"https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/api-application-monolith/src/index.ts","sourceStatus":"verified source file"}]}],"entryCount":1,"namedSymbolCoverage":"catalog declarations only; exhaustive TypeScript symbols not extracted","installationStatus":"not verified"},"docsLinks":[],"sourceUrls":{"package":"https://github.com/lssm-tech/contractspec/tree/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/api-application-monolith","manifest":"https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/api-application-monolith/package.json","readme":"https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/api-application-monolith/README.md","guide":"https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/web-landing/public/llms-packages/app.api-application-monolith.txt"},"readme":{"status":"available","body":"# Managed CompanyOS API Application Monolith\n\n## OPA production completion\n\n`GET/POST /api/v2/opa/automation-settings` exposes current-session policy ancestry\nand revision-checked updates. Apply additive migration 0073 before deployment.\nThe CompanyOS editor explicitly reports background execution as inactive while\ndelegation and effect-time worker binding remain unqualified. Saved planner\nplacements can be reviewed and added through the existing focus-create lifecycle;\nthe server rechecks saved identity, Work revision, and fresh availability.\n\nPersonal Planner generation now loads canonical Work and fresh calendar state,\npersists a proposal atomically with its command, and returns proposed placements\nand unscheduled reasons. Generation does not apply calendar changes. Active\norganization/workspace authority is checked again before committing.\n\nMeeting generation requires an explicit Vercel AI Gateway binding, pinned model,\nEU provider inference and separately approved global Gateway transit (see\n[Meeting AI through Vercel Gateway](#meeting-ai-through-vercel-gateway)).\nMissing configuration leaves generation unavailable;\nexisting artifacts remain readable. The approval reference is an operator\nconfiguration binding, not a substitute for processing review or model evaluation.\nAn explicit saved meeting policy must also enable AI suggestions or editing;\nmissing or disabled policy prevents model invocation.\nSee `docs/evidence/opa/production-completion-2026-09-04.md` for open release gates.\n\n## Durable CompanyOS onboarding preferences\n\n`PATCH /api/companyos/onboarding-preferences` implements the versioned\n`companyos.onboardingPreferences.complete@1.0.0` command. It accepts only a\nbounded experience-preference patch, expected tenant-scoped revision, and\nidempotency key. User and tenant authority always come from the verified\nsession. Migration `0071` stores one document per user and tenant; exact replay,\nconflicting replay, concurrent revision fencing, cross-user isolation, and\ncross-tenant isolation are covered by the PGlite repository proof. The existing\nauthenticated shell-preference query returns the validated persisted document\nso a subsequent page load hydrates the same experience.\n\n## OPA meeting provider intake\n\n`createCompanyOpaMeetingIntake` composes the provider-neutral intake binding\nwith the CompanyOS OPA operation registry, so automatic recorder matches pass\nthrough the same session-derived authority and governed\n`opa.recording.source_bind` handler as interactive requests. The host factory\naccepts the real Google or Outlook calendar adapter and Granola or Fireflies\nrecorder adapter without embedding credentials.\n\nMigration `0063` installs the owner-scoped occurrence and immutable review\ntables; `0065` adds recurring definitions and token-fenced execution leases.\nWhen callers do not inject narrower ports, the production composition uses this\nSQL store for current recorder-binding revisions and mandatory review requests.\nThe deployable worker remains fail-closed until its allowlisted composition\nsupplies selected calendar OAuth/Graph credentials, recorder credentials, and\nprotected configuration resolution. No provider or fixture is selected\nimplicitly.\n\n## SupportOS to OPA destination authority\n\n`POST /internal/opa/support/destinations/resolve` is the only server-to-server\nbridge that turns a SupportOS opaque profile or booking destination reference\ninto a public CompanyOS URL. It verifies a short-lived AuthOS grant for the\n`companyos-opa-support` audience and exact tenant, workspace, case, handoff, and\ndestination binding. The database query independently scopes the stable OPA\n`profile_ref` or `link_ref`, requires a published current profile/link revision,\nand never returns provider or calendar data. Configure\n`COMPANYOS_OPA_SUPPORT_AUTHOS_GRANT_VERIFY_URL` and\n`COMPANYOS_OPA_SUPPORT_AUTHOS_WORKLOAD_TOKEN`; `APP_WEB_BASE_URL` remains the\ncanonical public origin.\n\n## CompanyOS Briefings 2.0\n\nCalendar intelligence is recipient-owned. The scheduler reads only selected Google calendars attached to the authenticated user's non-shareable personal context; workspace booking resources are never briefing sources. Missing personal OAuth, selections, or authority fails closed as `setup_required` with no provider read or delivery. The ledger stores digests, state, composition metadata, and authorized evidence refs only—never notes, graph content, or email bodies. Outbound email has exactly one recipient: the user's verified CompanyOS delivery address. Authenticated preview requests select either `morning-recap` or `meeting-preparation` and cannot select a recipient; the server runs only the current user's bounded personal calendar and freshly authorized graph pipeline without persisting event content or rendered bodies.\n\nMigration `0068` deterministically replaces any historical raw or missing\nbriefing provider message identifier with a one-way\n`provider-message:sha256:*` reference before installing its provider-evidence\nconstraint. This keeps forward replay compatible with legacy successful\ndeliveries without retaining provider identifiers in the governed ledger.\n\nScheduled rollout is server-derived and cannot be selected by the browser. It\nbecomes `live` only after personal calendar setup is `ready` and at least one\ndelivery cadence is enabled; disabling both cadences or losing setup readiness\natomically returns it to `off`.\n\nMigration `0043` binds every source to the same user's active personal OAuth connection with a composite foreign key and generated owner reference. Production promotion uses the non-automatic, approval-gated `db/cutovers/companyos-briefings-v2.sql` transaction after the canary, backup, and zero-legacy-read replay; automatic migration must not remove V1 storage before those gates pass. Run `bun run companyos:briefings:postgres:test` against a disposable PostgreSQL URL for the owner, RLS, occurrence, and cutover proof.\n\n## Company Intelligence governed learning persistence\n\nS9 persists the governed-learning lifecycle through the existing migration\n`0022` canonical records, refs, receipts, and events plus the `0023`\ntransactional outbox. The transaction-scoped repository takes a lifecycle\nadvisory lock, verifies the expected sequence/head, validates a packet-closed\nhistory, and delegates canonical append/idempotency. There is no dedicated\nlearning table, index, provider call, export, or live canary. Migration `0027`\nbelongs to S10 API replay and budget state; governed-learning history remains\non the canonical `0022`/`0023` authority. S10 exposes the four authenticated\ngoverned-learning routes through this repository and fails closed when\n`LSSM_STUDIO_DATABASE_URL` is absent. FORCE RLS remains tenant-scoped; run\n`bun run test:company-intelligence:governed-learning-persistence` and the local\nPostgreSQL proof before changing this boundary.\n\n## Company Intelligence Brain persistence\n\nMigration `0026` adds one append-only FORCE-RLS object-version table for the\nCompanyOS-owned Brain entry, review, edition, gap, remediation, and compiled\nartifact families. The repository reuses canonical Company Intelligence\nreceipts/events, rejects static/demo fixture sources in production, binds every\nquery to tenant and workspace scope, keeps valid and recorded time distinct,\nand applies capability/field redaction before projection. Run\n`bun run test:company-intelligence:brain`; both managed PostgreSQL 15 proof\nscripts execute the same corpus under `NOSUPERUSER NOBYPASSRLS`.\n\n## Company Intelligence durable graph and identity\n\nMigration `0025` adds FORCE-RLS query projections and append-only identity\ncandidates, reviewed decisions, aliases and merge/split lineage over the\ncanonical `0022` record/event authority. Canonical content fingerprints bind\nreplay to the complete request. The repository rejects conflicting replay,\ncross-tenant decisions and label-only auto-linking, and exposes deadline- and\nedge-bounded traversal that authorizes every recursive branch. Run\n`bun run test:company-intelligence:graph-repository` for the exact package\ncorpus. `bun run companyos:db:prove-existing-postgres` (or the disposable\nPostgreSQL proof) executes its S6 integration test against PostgreSQL 15 under a\nconstrained `NOSUPERUSER NOBYPASSRLS` runtime role.\n\n## Company Intelligence tenant persistence\n\nMigrations `0022` and `0023` provide the additive app-owned PostgreSQL/Drizzle\nauthority for the canonical G002 Company Intelligence contracts: bitemporal\nrecords and normalized references, append-only receipts/events, controlled\ntombstone purging, and durable job/outbox/DLQ/backfill state. Every table uses\nFORCE RLS; runtime qualification authenticates as a `NOSUPERUSER NOBYPASSRLS`\nrole and proves cross-tenant read/write denial.\n\nRun `bun run companyos:db:prove-disposable-postgres` for the isolated Docker or\nnative-cluster proof. When a PostgreSQL 15 server is already running locally,\n`bun run companyos:db:prove-existing-postgres` creates two unique loopback test\ndatabases, runs the same S2 migration/recovery/repository/RLS checks, and drops\nboth databases. See\n[`docs/company-intelligence-persistence-runbook.md`](./docs/company-intelligence-persistence-runbook.md)\nfor resumable backfill, corruption checks, forward repair, and purge controls.\nUse\n[`docs/company-intelligence-operations-runbook.md`](./docs/company-intelligence-operations-runbook.md)\nfor readiness, safe metrics and budgets, correlation troubleshooting, kill\nswitch recovery, and the executable S12 qualification commands.\n\n## Company Intelligence continuous ingestion\n\nS4 reuses the same `0022`/`0023` authority without adding tables. Upload,\nwebhook, polling, and connector deliveries enter one idempotent durable job\npath for initial/incremental sync, backfill, resync, cancel, deletion, ACL, and\nidentity changes. Claims use bounded leases, heartbeats, optimistic checkpoints,\ndeterministic retry/backoff, quotas, cancellation, DLQ evidence, and resumable\ncursors. Duplicate delivery keys create one job and replayed record commits\ncreate zero additional effects.\n\nThe provider-neutral registry binds direct ingress, Drive, Gmail, Slack, Teams,\nGitHub, Linear, Jira, Notion, and meeting transcripts to their existing\nintegration/package owners. CI uses caller-supplied canonical deterministic\ncontract fakes; it never substitutes fixtures when credentials are missing.\nRequired credentials resolve outside job payloads through opaque provider\nsession handles. Missing credentials produce `not_run` plus\n`missing_credentials`, a durable redacted receipt/DLQ entry, and zero provider\ncalls.\n\nSource deletion and ACL revocation cancel queued work and append immutable\nsuperseding tombstones through the current canonical record closure (source,\nsource version, asset, part, fragment, evidence, and current dependent records).\nNo S5-S9 graph, Brain, retrieval, or public API behavior is implied.\n\nRun `bun run test:company-intelligence:ingestion` for deterministic connector\ncontracts and `bun run companyos:db:prove-disposable-postgres` for the complete\nlease/checkpoint/propagation/RLS qualification.\n\n## Company Intelligence structured extraction\n\nS5 adds strict model-output candidate schemas and a pure trusted runtime that\nalone resolves authorized pre-existing evidence IDs and exact locators into\ncanonical records. Invalid output, invented or cross-tenant evidence, locator\ndrift, instruction-like content, policy override attempts, and model-declared\napproval produce stable typed rejections with zero canonical effects.\n\nConfidence below `0.75` and high/critical risk require a separately supplied\ntrusted review decision. Redacted deterministic receipts record model, prompt,\nschema/runtime versions, cost, evidence, dispositions, and correction lineage\nwithout raw source/provider content. Migration `0024` adds only a nullable JSONB\ndetails column to the existing generic receipt table; the existing canonical\nrecord repository remains authoritative. The disposable PostgreSQL proof covers\nfirst commit, exact replay, immutable correction history, and tenant denial.\n\nThe v2 profile backend is mounted at `/api/v2/opa/profile/*` for\nsession/RBAC-scoped administration and `/api/v2/public/profiles/:handle` for\nthe redacted latest-published projection. Mutations require trusted origin and\na session-bound CSRF token; admin responses are always `no-store`. The\ndeployed composition lazily binds the transactional SQL profile repository to\n`LSSM_STUDIO_DATABASE_URL` and fails closed when it is absent. The in-memory\nprofile store is available only through explicit test/demo injection.\n\nThe public response and admin redaction boundaries omit private topology and\nprovider references. Draft restoration accepts newly created hybrid events but\nrejects newly invented owned-live events until authoritative provisioning\nexists. Cache and publish/revoke invalidation remain server-owned. OPA v1\nbooking contracts are unsupported; promotion remains blocked until G004b binds\nand verifies the exact v2 runtime and API handlers.\n\nG004b Phase B is implemented locally. Canonical migration `0037` remains absent\nfrom default migration discovery and is not production-promotable without a\nfresh, exact-target opaque activation minted from an independently trusted\nEd25519 reset authorization. That authorization digest-binds the `0036` ledger\nhead and exact `0037` digest to ordered external snapshot, schema, restore,\nruntime build/test, ContractSpec Connect decision/replay, actor, and observed\ndatabase proof. Application revalidates the target and time window immediately\nbefore any migration work and spends the activation once. No external evidence\nbundle is checked in, so this package does not claim a canary or production\nactivation.\n\n## Managed Google Meet booking persistence\n\nMigration `0028` adds protected primary and staged-replacement conference state\nto the canonical tenant/RLS-scoped booking intent. Published owned-live event\ntypes carry their provider-neutral conference mode into both public booking\nentrypoints. The provider-effect worker confirms a Meet booking only after a\nverified `https://meet.google.com` link is encrypted in the same fenced\ntransition; pending, failed, and ambiguous creation stays recoverable by exact\nknown ID. Cancellation clears the link, while rescheduling promotes only the\nready encrypted replacement after definitive old-event cancellation.\n\nThe canonical `opa.profile.public_list@2.0.0` REST identity is\n`GET /api/v2/public/profiles`. The Elysia host exposes that route plus\n`GET /api/v2/public/profiles/readiness`; handler contract tests freeze those\nv2 gateway mappings.\n\nReal API monolith for tenant-scoped Managed CompanyOS commands and queries.\n\n## Company Intelligence authenticated API\n\nThe Elysia host mounts the contract-derived v1 surface at\n`/api/companyos/company-intelligence/v1/*`. Every operation requires a\ntenant-bound user session or service principal, returns private no-store\nresponses with API and correlation headers, and enforces bounded bodies,\npagination, timeout, budget, and idempotency semantics. Migration `0027`\npersists tenant-scoped replay results and minute request budgets with integrity\nconstraints and FORCE RLS, so new handler instances preserve both controls.\nProduction has no fixture fallback.\n\n`GET /api/companyos/company-intelligence/v1/surface?surface=<id>` resolves the\nauthenticated overview, sources, Brain, graph, assistant, learning, or\noperations descriptor before browser data reads. The handler accepts exactly\none logical `surface` query parameter and rejects tenant or role input. It\nreturns canonical route, truthful route state, safe-read posture, action\navailability, and dependency blocks derived from the authenticated actor and\nserver composition; missing PostgreSQL composition is reported as degraded\nrather than replaced with demo data.\n\nConnections, jobs, uploads, evidence, reviews, graph traversal, Brain reads,\nreplay, health, and the four governed-learning mutations bind canonical\nPostgreSQL repositories or tables. Structured extraction and grounded answers\ndelegate authorization-aware retrieval to explicitly bound production services\nwithout preloading tenant-wide records. Evidence and replay reads, reviewed decisions, graph traversal, and Brain\nprojections use built-in PostgreSQL ACL/workspace authority adapters. Health is\n`degraded` until the external extraction and grounding services are bound; those\ntwo operations alone fail closed with `503 dependency_unavailable` when absent. Run\n`bun run test:company-intelligence:api` for parity, auth, isolation, limits,\ndurable idempotency/budgets, degraded behavior, cancellation, and log safety.\nThe disposable PostgreSQL 15 proof covers restart replay, tenant-key isolation,\nbudget continuity, and constrained `NOSUPERUSER NOBYPASSRLS` denial.\n\n## Company Intelligence operational safety\n\nS12 operational controls reuse the canonical append-only PostgreSQL receipt and\nevent authority for dependency health, kill-switch changes, and pre-dispatch\naudit decisions. Missing switch state fails closed. Ingestion and connector\ndispatch recheck the durable `ingestion` and `connector_dispatch` switches\nbefore every provider call; blocked jobs return to retry without consuming an\nattempt. Run `bun run company-intelligence:failure-injection` from the repository\nroot to prove database, vector, model, queue, and connector degradation, all six\naudited switches, recovery within twice the outage duration, safe correlated\ntelemetry, and disposable PostgreSQL cleanup.\n\nADR-008 reference qualification is fail-closed and never shortens the required\n60-minute load plus 8-hour soak. Run\n`bun run company-intelligence:reference-qualification` to validate the exact\n10-tenant corpus manifest, pull and verify PostgreSQL 16, Qdrant 1.15.0, the\nlocked Qdrant 1.18.0 adapter, and Bun 1.4.0 runner, then launch both phases as\none durable background process. Before load begins, a pinned Bun runner applies\nthe tracked database migrations and fails closed unless\n`managed_companyos_ci_records` and `managed_companyos_ci_jobs` both resolve in\nPostgreSQL and the digest-backed migration ledger matches versions `0022` and\n`0023`. The command records leader-owned environment, schema-preflight,\ncontainer, image-digest, PID, and log handoff evidence. Docker allocations below\n8 CPUs or 16 GiB fail with a concrete `blocked` packet and launch no\nqualification; such a packet is not S12-A3 completion.\n\n## Google Calendar booking edge\n\nThe Elysia host owns protected OAuth start/callback/disconnect routes under\n`/api/companyos/integrations/google-calendar/*` and the authenticated\n`/api/cron/google-calendar-maintenance` polling/reconciliation route. Runtime\nconfiguration is server-only and uses `MANAGED_COMPANYOS_GOOGLE_CALENDAR_*`\n`CLIENT_ID`, `CLIENT_SECRET`, and exact `REDIRECT_URI`; tenant/account/calendar\ntopology is enumerated from durable `opa_calendar_connections`. OAuth tokens and\ntheir granted scopes/expiry bind to the ciphertext-only OPA vault. Callback and\ndisconnect persist tenant/account-scoped connection state; disconnect disables\nthe local connection before remote token revocation. Exact-scope drift records\n`reauthorization_required` before best-effort revocation of rejected grants. The maintenance\ncron isolates each tenant, refreshes only near expiry, proves paginated\nCalendarList owner/busy topology, polls durable free/busy snapshots, and durably\nschedules daily known-ID reconciliation without broad event listing.\n\nEvery request-time free/busy read, freshness refresh, booking event creation,\nGoogle Meet creation, cancellation, reschedule, and reconciliation resolves an\nexplicit `(tenant, workspace, scheduling resource, write calendar)` binding.\nThe booking saga keeps the tenant-scoped write-calendar reference as its stable\nidentity; immediately before every Google call, the trusted adapter resolves it\nto the current provider calendar identifier. The provider identifier is never\naccepted from or returned to the anonymous booking browser.\nOne connected Google account may serve multiple workspaces only when each\nworkspace has its own persisted scheduling preference joined to that resource\nand connection. Missing, foreign, contradictory, or ambiguous bindings fail\nbefore snapshot, OAuth vault, protected booking, or Google provider access.\nPersonal mode uses the same contract with its personal workspace authority.\nConnection-wide maintenance can probe and refresh a connected account, but it\ndoes not grant request authority to any workspace. Migration\n`0033_google_workspace_availability_snapshots.sql` partitions opaque snapshots\nby tenant, workspace, and scheduling resource while retaining legacy\nmaintenance rows in an explicit empty-workspace partition. Malformed timestamps\nor busy intervals fail closed.\n\nThe production integration keeps booking availability free-busy based and uses\nthe separately consented read-only event scope only for bounded daily\nintelligence. `events.list` is capped at 40 events per user/run. Raw event\ntitles, descriptions, attendees, locations, bodies, and email content are\nnever persisted; only delivery state and content digests are durable.\n\nThe Google and Microsoft readers keep attendee addresses beside the display\nlabels (`CalendarIntelligenceMeeting.attendees`, contract 2.7.0) under\n`COMPANYOS_CALENDAR_ATTENDEE_ADDRESS_POLICY`. Shared pre-meeting briefs use\nthem to propose recipients, so named attendees are no longer missed; the owner\nstill reviews every recipient. They are stripped from the briefing model input\nand redacted from log lines. The only stored copy is a shared-brief draft's\nrecipient list, which the owner reviews.\n\n## Live profiles, booking surfaces, and daily intelligence\n\nMigration `0042` adds evidence-only calendar-intelligence preferences and\ndelivery attempts, canonical owner scopes for the existing OPA profile/calendar\ntables, and the public published-profile lookup boundary. The\n`core-workspaces` (and `all`) bootstrap profile reconciles the live LSSM and\nCompanyOS organizations. Hirly and NDconsulting were decommissioned in\nproduction on 2026-10-20 ([evidence](../../../docs/evidence/authos/decommission-hirly-ndconsulting-2026-10-20.md)); no live profile recreates\nthem. Collaborators join through the invitation flow and are never seeded as\nadmins.\n\nAfter every target workspace has a connected Google Calendar topology, run\n`bun run companyos:booking-surfaces:activate`. It publishes shared links for\nLSSM and CompanyOS plus Théo's personal link (`/u/theo`). The former Hirly\nsurfaces (`/u/hirly`, `/u/hirly-talent-team-booking`) are unpublished.\nEach surface uses Europe/Paris weekday availability, Google Meet, bounded\nadvance/notice policy, and the workspace-owned scheduling resource.\nActivation advances the canonical link to the published profile revision and\nrevokes active links from superseded revisions, so a replay cannot expose a\ndead booking URL. It also reconciles the exact first-party\n`https://www.companyos.run` embed origin on all three canonical links so the\nhosted loader and React canary work immediately. Every additional embedding\norigin remains an explicit owner-managed allowlist entry.\n\nCanonical owner/admin authority must include the complete owner capability\nset (`COMPANYOS_OWNER_CAPABILITIES`, which contains the Meeting Intelligence\nset) at the organization, workspace-default, and user-workspace layers.\nBootstrap provisions that set for new personal and organization contexts.\nExisting LSSM and CompanyOS grants converge additively\nwith `bun run companyos:opa:reconcile-meeting-authority`: run it first with\n`COMPANYOS_OPA_MEETING_AUTHORITY_RECONCILE=dry-run` (writes nothing, prints the\nmissing capabilities per layer), then with `=1` to apply. The owner set is a\nfloor: separately reviewed extras such as `builder.*` are preserved, and the\n`companyos:db:verify:live` bootstrap prerequisite checks containment rather\nthan exact equality. Team grants only receive the Meeting Intelligence set.\nThe owner set includes `opa.plan_run.manage`, which background planning\nreproves on both the company workspace and the owner's personal context, so the\ncommand also reconciles the canonical owner's personal context. Members get the\nsame self-scoped capability through the `frontline_staff` template (also the\njoined-member default; OWNER-DECISIONS-2026-10-19); existing member grants\nreceive it on re-grant or through the joined-template authority repair.\nPlanning counts sessions already added from earlier plans (active\nplanner-sourced focus blocks) as scheduled time, so a re-plan never proposes\nthem again or reports them as moved.\nThe command targets only the canonical owner on the live organizations and\nincrements each changed authority revision so existing sessions fail closed\nuntil refreshed. Prefer it over re-running `companyos:bootstrap-admin` on a\nlive target: bootstrap rewrites grants to the exact set (dropping reviewed\nextras) and re-enables calendar-intelligence preferences.\n\nOwners can revise an active link's embed allowlist through\n`POST /api/v2/opa/links/:linkRef/embed-origins`. The command requires the\nserver-derived opaque `scopeRef`, same-origin CSRF authority, and the current\nlink revision. It replaces the complete list with unique exact HTTPS origins;\npassing an empty list returns the link to hosted-only mode without changing its\npublic token.\n\nProtected profile execution uses the exported v3 profile operation version and\nrequires a server-authorized opaque `scopeRef`. Booking approval is available\nonly through the canonical scoped\n`POST /api/v2/opa/bookings/:bookingRef/approval` operation. The former\n`/api/companyos/booking-approvals/:bookingRef/decide` host alias is removed\nbecause it could not satisfy the v3 owner-scope authority contract.\n\nProduction credential recovery requires the exact rotation confirmation and an\nunused permission-restricted path below `/tmp` via\n`OPA_ADMIN_PASSWORD_DELIVERY_FILE`. The rotation command writes the generated\npassword only to that mode-`0600` file and never prints it or stores it in the\nrepository.\n\nThe `/api/cron/calendar-intelligence` route runs every five minutes. It sends a\nEurope/Paris morning recap once per local day and a preparation email in the\nfive-minute window one hour before each meeting. Model composition is temporarily\npaused at the host: existing Mistral environment values cannot enable it. The\nlocalized deterministic-v2 fallback keeps delivery available without persisting\nsource calendar content. Preview delivery failures return the stable\n`briefing_delivery_unavailable` 503 projection; provider response bodies and\ncredentials are never returned to the browser.\n\nThe protected admin topology endpoints list every paginated provider\n`CalendarList` option, then re-enumerate before atomically materializing the\nselected owned-write/readable-busy topology and Europe/Paris working hours,\nbuffers, notice, horizon, and approval mode. Tenant identity comes only from the\nauthenticated session; identifiers absent from the current provider response\nare rejected.\n\nBooking lifecycle recovery uses the exact active original or replacement slot and the\npersisted saga-owned provider identity. App-owned provider-effect and notification\noutbox rows are atomically leased with tenant/owner fencing before relay.\nNotifications use the durable SQS queue when\n`MANAGED_COMPANYOS_BOOKING_QUEUE_URL` and the protected delivery service are\nconfigured. Serverless deployments without that pair drain the same Postgres\noutbox directly: recipient material is decrypted only after a token-fenced\ndelivery claim, Resend receives the durable dedupe key as its native\nidempotency key, and the email management grant stays in the URL fragment until\nthe hosted page exchanges it for HttpOnly cookies. Provider calls are mocked in\nrepository tests; production qualification still requires a reversible live\ndelivery canary.\n\n## Smart-meeting preparation\n\nThe authenticated `GET|POST /api/companyos/opa-os/manual-loop` surface composes\nthe existing authorized OPA manual loop for Managed CompanyOS. Session authority\nowns tenant, workspace, organization, actor, and role scope. The request body\ncontains meeting intent only and strict parsing rejects browser-supplied\nauthority or provider identifiers.\n\nPreparation authorizes before Google work, selects calendar preferences by the\nsession-derived tenant and active workspace, refreshes free/busy through the\nproduction calendar bridge, and labels availability as fresh, cached, or\nunavailable. Readiness distinguishes normal setup states from an explicit\nruntime outage. It then atomically persists the plan, agenda, booking\nproposal, immutable command audit, and `opa.plan.proposed` outbox signal. Exact\nidempotent replay returns the original redacted receipt; conflicting reuse\nreturns `409`. The response remains `pending_approval` with external effects\nblocked. No calendar event or Google Meet link is created by this endpoint.\nMigration `0031_smart_meeting_workspace_calendar.sql` preserves legacy\ntenant-only preferences but requires an authorized workspace binding before\nthey can participate in smart-meeting readiness.\n\nThe separate authenticated `/api/companyos/smart-meetings` lifecycle exposes\ntenant/workspace-scoped list and status reads plus receipt-scoped approval,\ncancel, and reschedule mutations. Enterprise admins and founder approvers may\nmutate the lifecycle; operations managers may prepare and monitor but do not\nreceive external-action approval authority. Approval re-enumerates the active\nworkspace topology, refreshes the selected slot, and links the proposal exactly\nonce to the canonical booking saga. The existing fenced provider-effect worker\nthen owns Google Calendar and optional Google Meet creation; browser and route\nhandlers never call Google directly. Cancellation and rescheduling reuse the\nsame durable leases, deterministic provider identity, reconciliation, and\noutbox path.\n\nApply `0032_smart_meeting_booking_lifecycle.sql` before enabling this lifecycle.\nIt adds nullable forward linkage from the smart-meeting proposal to the\ncanonical booking intent, preserving all existing proposals and enforcing\ntenant-scoped uniqueness for new links.\n\nOperator qualification is documented in\n[`docs/runbooks/opa-smart-meeting.md`](../../../docs/runbooks/opa-smart-meeting.md).\n\n## Resend purpose ownership and signed status ingress\n\nAuth mail uses `AUTH_EMAIL_FROM` as\n`CompanyOS Security <security@notifications.companyos.run>`; booking mail uses\n`RESEND_BOOKING_FROM` as\n`CompanyOS <bookings@notifications.companyos.run>`. Both share an explicit,\nvalidated `RESEND_REPLY_TO`, and all three addresses are parsed once before a\nprovider call. Auth callbacks may send directly through the auth-owned provider.\nBooking code attaches its owned sender only at the protected delivery\nservice and durable outbox claim/dedupe/retry/reconciliation path; it must not\ncall the auth sender.\n\n`POST /webhooks/resend/events` reads the raw request body and verifies\n`svix-id`, `svix-timestamp`, and `svix-signature` with\n`RESEND_WEBHOOK_SECRET` before parsing. Duplicate `svix-id` deliveries return a\nreplayed status and do not re-apply the status projection. Production replay\nand status authority lives in the caller-owned PostgreSQL tables created by\nmigration `0014`; a unique `event_id` plus a transactional monotonic upsert keeps\nrestart and concurrent-instance delivery safe. Stored rows and API results bind\nonly deterministic `provider-message:sha256:*` references, status, and\ntimestamps—never raw provider message ids, signed payloads, or webhook secrets.\nDistinct, older events remain recorded but cannot regress the current message\nstatus. In-memory storage is test-injected only. This ingress is observational:\nthe booking outbox and protected delivery receipt remain the durable delivery\nauthority. Repository verification never registers a webhook or calls the live\nResend API.\n\nCalendar-intelligence email selected through CommunicationOS is admitted to the\ncanonical journal and domain-command outbox before dispatch. The ledger records\n`queued` separately from provider acceptance and delivery. The shared worker\nresolves only the opaque\n`env://COMMUNICATION_OS_CONNECTION_COMPANYOS_CALENDAR_RESEND` credential\nreference, forwards one stable provider idempotency key, and exposes\n`reconciliation_pending` if provider acceptance cannot be durably completed.\nMigration `0069_calendar_intelligence_queued_delivery.sql` is required before\nenabling `COMPANYOS_CALENDAR_OMNICHANNEL_ENABLED=1`.\n\n> **api-monolith-elysia-convergence:** this app is now verified as a single **Elysia host** (`src/app.ts` + `api/index.js` `@vercel/node` entry). Former Next.js App Router handlers have been removed from `src/app/api`; route tests exercise `app.handle(Request)` directly. The `vercel.json` deploy flip and external webhook re-registration remain human-gated, but source ownership, tests, and local builds are Elysia-owned. Build the host with `bun run build:elysia`.\n\nMost proof handlers remain deterministic until their production adapters are explicitly approved. The Managed CompanyOS v2 design-partner routes are an exception: production uses the app-owned Postgres repository and fails closed when its database, migration, tenant kill switch, or evidence relay health is unavailable. Provider strategy remains app-layer and secret-reference-only; bundle/libs/modules remain provider-neutral.\n\nThis implementation supports persisted multi-organization authority for the\nstable canonical slugs. Only `lssm` and `companyos` are live; `ndconsulting`\nand `hirly` were decommissioned on 2026-10-20\n([evidence](../../../docs/evidence/authos/decommission-hirly-ndconsulting-2026-10-20.md)). A verified Better Auth\n`activeOrganizationId` is an identity-plane key; an enabled one-to-one binding\nselects the physical tenant used by FORCE RLS. Production activation still\nrequires the rollout, evidence, and ownership gates in\n[`docs/runbooks/managed-companyos.md`](../../../docs/runbooks/managed-companyos.md).\nThe former private-pilot configuration remains migration history and rollback\ninput only; it is not forward authorization.\n\n`GET /api/companyos/workspaces` is a private authority projection. Every\nsuccess, deny, and degraded response sets `Cache-Control: private, no-store`;\ntrusted-origin credentialed CORS never makes the response share-cacheable. The\nroute lazily creates one app-owned Postgres authority repository/pool, reuses it\nfor the Elysia host lifecycle, and closes it on host shutdown. It never creates\nor tears down a pool per request.\n\n## Personal, company, team, and workspace authority\n\nMigration `0055_companyos_shell_preferences.sql` adds one user-scoped,\noptimistically versioned shell-preference row and a nullable session preview\npersona. `GET/PATCH /api/companyos/shell-preferences` synchronizes context\nplacement across devices. `GET/POST /api/companyos/persona-preview` authorizes\nEnterprise Admin by default, stores presentation preview only in the current\nsession, and returns a safe current route or persona home. Context changes and\nsession expiry clear preview; the real session role remains authoritative.\nMigration 0160 adds a tenant-keyed `opa_home_modes` map to the same row:\n`GET/POST /api/companyos/opa-os/home-mode` (`companyos.opaHomeMode.*`,\n`workspace.read`) reads or sets the OPA OS landing view for the session's own\norganization (at most 50 organizations remembered); the web app keeps its\nper-tenant cookie only as a cache for when the API is unavailable.\n\nThe additive context family lets an authenticated user operate without a\ncompany and switch among one or many companies, teams, and workspaces:\n\n- `POST /api/companyos/personal-context/ensure`;\n- `POST /api/companyos/personal-context/disable`;\n- `GET /api/companyos/contexts`;\n- `POST /api/companyos/contexts/set-active`.\n\nMigration `0029_personal_context_authority.sql` adds the system-owned,\nnon-shareable personal-context manifest, session authority version, one-use\nnonce digests, and idempotency receipts. Database triggers reject a second\nmember, invitation, or team in a personal organization. Personal ensure creates\nthe existing tenant/binding/grant/workspace topology idempotently; disable\nrevokes binding, grant, public intake, OAuth tokens, and matching active session\nscope without deleting evidence.\n\nMigration `0030_team_context_authority.sql` adds canonical direct-user\nworkspace, team, and team-workspace grants plus workspace authority versions.\nExisting enabled organization/workspace authority is materialized as explicit\ndirect grants during migration; new workspaces require an explicit grant. The\nset-active\ntransaction locks the session, consumes the signed five-minute token once,\nrevalidates organization, team, grant, workspace, and projection versions, then\nupdates active organization/team/workspace and emits exactly one\n`context.activeChanged` event. Request middleware freshly resolves the selected\ntuple and intersects organization, team, and workspace capabilities; revoked or\nstale nested authority fails closed before a protected handler runs.\n\nOnly explicitly granted workspaces are listed or accepted at commit time. Opaque\n`contextRef`, `teamRef`, and `workspaceRef` values cross the public\nboundary. They are locators, not credentials. Physical tenant identifiers remain\nserver-derived and are never accepted by these routes. Repository-local PGlite\nproves ensure replay, anti-share enforcement, one-use CAS, stale-token denial,\nteam grant selection, and revocation denial. A real PostgreSQL migration/RLS\nqualification and live deployment remain separate rollout gates.\n\n## Vercel-only Managed CompanyOS production topology\n\nManaged CompanyOS production is cost-capped to the Vercel-hosted web and API monoliths. The API monolith absorbs required background duties through request-time HTTP snapshots and Vercel Cron handlers; it must not require the standalone Bun worker or any browser-held realtime connection for production readiness.\n\nThe legacy `builds` entry in `vercel.json` makes Vercel ignore the dashboard\nBuild Command. The repository root `postinstall` therefore dispatches on the\nVercel project id and runs this package's `build:elysia` script during install,\nbefore `@vercel/node` traces `api/index.js`. That build must bundle `src/app.ts`\nto both `dist/index.js` and `api/dist/index.js`. The Vercel adapter deliberately\nloads the generated module through an opaque runtime path and `vercel.json`\nexplicitly includes only `api/dist/index.js`; this prevents Node File Trace from\nre-analyzing the 70+ MB pre-bundled file or packaging the second local-runtime\ncopy.\n\nImplemented route families include retained design-partner-named compatibility\nadapters. Those adapters preserve NDconsulting history and remain scoped to\n`tenant_ndconsulting_special_ops` / `workspace_ndconsulting_special_ops`; their\nnames do not make pilot identifiers an authorization source.\n\n| Purpose | Route |\n| --- | --- |\n| Graph/status snapshot | `GET /api/companyos/vercel/snapshot` |\n| Replay/evidence snapshot | `GET /api/companyos/vercel/replay-evidence` |\n| Supervision-equivalent snapshot | `GET /api/companyos/vercel/supervision` |\n| Manual integration sync trigger | `POST /api/companyos/integrations/sync-trigger` |\n| Scheduled snapshot trigger | `GET /api/cron/companyos-snapshot` |\n| Profile cache invalidation dispatch | `GET /api/cron/profile-cache-invalidation` |\n| Design-partner evidence relay | `GET /api/cron/companyos-design-partner-evidence-relay` |\n\n`/api/cron/companyos-snapshot` is service-principal gated with the same `control-plane.core` authorization path as other Vercel crons. User-facing reads remain tenant-session scoped and cross-tenant requests fail closed.\n\nPublic profile reads, including 404 responses, use `Cache-Control: no-store`\nuntil a web cache invalidation provider is configured. Publish/revoke signals\nare durably leased, retried, and emitted by the authenticated profile cache cron.\n\n## Runtime surface\n\n- `src/app.ts` — authoritative Elysia host composition for `/api/auth/*`, `/api/companyos/*`, `/api/companyos/builder/*`, webhooks, crons, schemas, control-plane, billing, and waitlist routes.\n- `api/index.js` — Vercel Node adapter from `(req, res)` to Web `Request` to `app.handle(request)`.\n- `src/handlers/auth-handler.ts` — better-auth catch-all with readiness gates, observability, and credentialed CORS.\n- `src/handlers/companyos/companyos-status-handler.ts` — tenant-scoped Managed CompanyOS read routes (`health`, `database`, `evidence`, `providers`, `integrations`, `replay`, `workflow`, `workspace`, `surface`, `health/degraded`) plus Vercel-only snapshot routes (`vercel/snapshot`, `vercel/replay-evidence`, `vercel/supervision`) and the manual integration sync trigger.\n- `src/handlers/companyos/companyos-command-handler.ts` — verified-session command routes (`integrations/setup`, `workflow/approve`).\n- `src/handlers/companyos-auth-*.ts` — invitation, lockout, passkey, sign-out, test-login, and sibling-session revoke routes.\n- `src/handlers/companyos/*special-ops*.ts` — Special Ops and AI Ops Sprint scoped route families.\n- `src/handlers/companyos/design-partner-readiness-handler.ts` — design-partner Special Ops v2 routes for persisted readiness, expert attestation, and founder approval; production derives authority from the verified session and commits through one tenant-scoped Postgres transaction.\n- `src/handlers/builder/builder-public-handler.ts` — public Builder REST surface at `/api/companyos/builder/*`, distinct from agent/workflow.\n- `src/handlers/webhooks/*` — signed provider ingress (GitHub, Slack, Telegram, WhatsApp Meta/Twilio, Resend, OPA recorders and notetaker bots). Every edge logs through `src/observability/webhook-log.ts`, a binding over the hashing structured logger: records carry the webhook, the route template (never a route token), a correlation id (a well-formed `x-correlation-id`, `x-request-id` or `x-vercel-id`, else a generated `whk_` id) and the W3C `traceparent`/`trace_id` from a valid `traceparent` header. Fields are allowlisted: the tenant is hashed, an id that is not a plain token is digested, and an error keeps only its name, code and a message digest, so raw payloads, headers, secrets and provider error text are never logged.\n- `src/index.ts` — pure command/query functions shared by Elysia handlers and unit tests.\n\n## Design-partner readiness API routes\n\nThe design-partner readiness routes are the API monolith's sole authenticated\nruntime authority for the bounded private-pilot slice. When activated,\nproduction reads packet versions from Postgres; mutations atomically commit the\nhuman decision, durable receipt, audit event, evidence outbox intent, and replay\nevent. The response cannot claim tenant activation or broader production\nreadiness and returns HTTP 503 when database, migration, relay, DLQ, or\nscheduled-snapshot health is degraded. Migration\n`0011_design_partner_runtime_authority.sql` adds the server-owned tenant\n`enabled` kill switch and excludes disabled tenants from scheduled relay\nenumeration.\n\nThe fictive NDconsulting projection remains available only on explicit test/demo surfaces (`MANAGED_COMPANYOS_DESIGN_PARTNER_RUNTIME=fixture` outside production, or the jointly enabled test-login + test-session-header harness). Production never falls back to this fixture or process-memory receipts.\n\nCanonical fixture IDs:\n\n| Field | Value |\n| --- | --- |\n| Tenant ID | `tenant_ndconsulting_design_partner_demo` |\n| Workspace ID | `workspace_ndconsulting_desliance_demo` |\n| Scenario ID | `scenario_atlantique_industrie_mission_retournement` |\n| Scenario title | `Atlantique Industrie — mission retournement` |\n\nRoutes:\n\n| Method | Path | Role gate |\n| --- | --- | --- |\n| `GET` | `/api/companyos/special-ops/design-partner-readiness` | Read roles: founder, operations, expert, auditor, AI, frontline, enterprise admin; all remain tenant/workspace/feature scoped. |\n| `POST` | `/api/companyos/special-ops/design-partner-readiness/decision-packets/:packetId/attest` | `expert_reviewer` only; requires packet version, statement, and idempotency key; returns the durable receipt. |\n| `POST` | `/api/companyos/special-ops/design-partner-readiness/decision-packets/:packetId/founder-approval` | `founder_approver` only; requires an accepted expert attestation on the exact version; `enterprise_admin` is denied as a founder substitute. |\n\nDenied by contract: missing session, cross-tenant access, missing feature entitlement, wrong workspace, unknown packet id, auditor mutation, AI mutation, frontline mutation, operations attestation/approval, expert founder approval, founder expert attestation, enterprise-admin founder approval, and every provider/customer/legal/financial dispatch path.\n\n## Special Ops database-first cutover\n\nUse [`docs/runbooks/special-ops-monolith-production.md`](../../../docs/runbooks/special-ops-monolith-production.md) for the NDconsulting/Special Ops seed, tenant/workspace isolation, capability graph, AI Ops Sprint, and all-in-one work-graph promotion gates. The DB repository lane is implemented; live customer-data promotion remains blocked until its migration, RLS, backup, closed ND manifest, canary, and rollback evidence is approved.\n\n## Production prerequisites\n\nThe following items must be resolved before this app is promoted to production with real-tenant data. The design-partner v2 persistence and Vercel relay lane is implemented; unrelated deterministic proof lanes retain their own deferrals.\n\n| Prerequisite | Status | Detail |\n|---|---|---|\n| **JWT/session middleware for tenant identity** | ✅ **IMPLEMENTED** | All routes now derive `requestTenantId` from a verified HMAC-HS256 session token (`x-managed-companyos-session` header) via `src/middleware/session.ts`. Invalid or tampered tokens return 401. Set `MANAGED_COMPANYOS_SESSION_SECRET` to a strong secret before admitting real-tenant data. |\n| **Persistent storage adapter** | ✅ **IMPLEMENTED FOR MANAGED COMPANYOS TABLES** | App-owned Drizzle/local lifecycle paths use canonical `managed_companyos_*` tables for tenant, session, invitation, passkey, lockout, audit, replay/evidence, capability, and mutation-ledger state. External production DB access remains URL-gated; live credentials are not committed. |\n| **Production queue** | Approval-gated | Background job logic is in-process. A durable queue must be approved and wired before live workloads. |\n| **Provider strategy** | ✅ **IMPLEMENTED APP-LAYER REFERENCE CATALOG** | `src/production/providers.ts` exposes an executable provider-neutral catalog and dispatch adapter for managed-reference and BYOK-reference modes. The wider provider family matrix remains a readiness/runbook contract until each family has app/provider-layer smoke evidence. Dispatch accepts env-backed redacted reference aliases only and fails closed before the harness when refs are missing, raw-looking, or not redacted. |\n\nDo not activate organization authority until all prerequisites above and every\ndecision in `docs/runbooks/managed-companyos.md` has explicit approval artifacts\nand implementation sign-off. The archived private-pilot material is ND migration\nhistory, not the forward execution checklist.\n\n## Organization authority migration history\n\nHistorical migration `0012_better_auth_schema.sql` remains immutable and creates\nmissing Better Auth tables. Forward-only migration\n`0016_better_auth_partial_schema_evolution.sql` evolves empty partial schemas\nand fails transactionally when existing rows or column types cannot satisfy the\ncanonical schema. The migration ledger records each version only after its full\nschema validation commits.\n\nThe profile-aware bootstrap preserves existing credentials, requires\n`BOOTSTRAP_ADMIN_PASSWORD` only when `tboutron@lssm.co` does not yet exist, and\nrequires an explicit live profile instead of tenant/workspace selectors. The\nstable manifests own those values. Better Auth organization IDs are never\nassumed to equal physical tenant IDs.\n\n### Organization authority HTTP lifecycle\n\nThe API binds the public CompanyOS authority operations to real routes:\n\n- `GET /api/companyos/organizations`;\n- `POST /api/companyos/organizations/set-active`;\n- `GET /api/companyos/auth/authority`;\n- `GET /api/companyos/workspaces`.\n\nBrowser requests require the exact configured web Origin, ambient credentials,\nand explicit admitted `OPTIONS` preflights. Absent Origin is accepted only for\nserver transport. Every success, deny, conflict, and degraded authority\nprojection is `Cache-Control: private, no-store`.\n\nSet-active preserves every distinct provider `Set-Cookie` value through the\nElysia handler and Node response adapter, including cookies whose `Expires`\nattribute contains a comma. The post-write canonical authority read bypasses\nprovider and HTTP caches. Membership rejection returns `403`, stale or\nmismatched canonical authority returns `409`, and malformed or unavailable\nstores return retryable `503`.\n\nA session without an active organization may list only its current memberships\nand select one, but it receives zero workspace authority until canonical\nrevalidation succeeds. The host shares one lazy authority repository/pool\nacross requests and closes it during shutdown.\n\nMigration `0020_organization_active_audit.sql` installs a constrained\nsecurity-definer PostgreSQL trigger that records\n`organization.activeChanged` in the same transaction as a real\nactive-organization transition. Re-selecting the current organization emits\nnothing; invalid authority and audit insertion failure roll back the\ntransition, and provider-owned clearing emits no tenant event. Use the\ndisposable PostgreSQL commands in\n[`docs/runbooks/real-organizations-rollout.md`](../../../docs/runbooks/real-organizations-rollout.md)\nto prove migration, transition, no-op, and rollback behavior. Repository-local\nproof does not claim that a live production database was migrated or cut over.\n\n## Local commands\n\n```bash\nbun run --cwd packages/apps/api-application-monolith dev\nbun run --cwd packages/apps/api-application-monolith test\nbun run --cwd packages/apps/api-application-monolith typecheck\nbun run --cwd packages/apps/api-application-monolith lint:check\nbun run --cwd packages/apps/api-application-monolith build\nbun run --cwd packages/apps/api-application-monolith companyos:db:migrate:test\nbun run --cwd packages/apps/api-application-monolith companyos:db:seed:test\nbun run --cwd packages/apps/api-application-monolith companyos:db:verify:test\nbun run --cwd packages/apps/api-application-monolith companyos:db:prove-rls:test\nbun run --cwd packages/apps/api-application-monolith companyos:db:prove-disposable-postgres\n\n# Live/shared DB path: approval-gated, non-destructive, URL-redacting.\nbun run --cwd packages/apps/api-application-monolith companyos:db:migrate:live\nbun run --cwd packages/apps/api-application-monolith companyos:db:seed:live\nbun run --cwd packages/apps/api-application-monolith companyos:db:verify:live\n```\n\n`typecheck` runs two projects: `typecheck:build` (`tsconfig.build.json`, the\n`src/` sources that `prebuild` also gates) and `typecheck:scripts`\n(`tsconfig.scripts.json`, every `scripts/**/*.ts` operator script and its\ntests). The Postgres bootstrap recovery suite\n(`scripts/bootstrap-admin-postgres.test.ts`) runs only when\n`MANAGED_COMPANYOS_TEST_DATABASE_URL` points at a disposable local database.\n\n## Managed Builder public REST surface\n\nThe Elysia host exposes Builder operations at `/api/companyos/builder/*` as a\ntenant-scoped Builder surface distinct from agent/workflow. The public handler\nuses AuthOS/control-plane service-principal authorization, rejects raw-looking\nprovider or webhook credentials, and reuses the Builder runtime resources that\nselect DB-backed storage by default (or `BUILDER_RUNTIME_STORAGE=memory` for\ntests). Key route families include sessions, sources, intents, spec packs, plan\ncompile/tasks, provider preflight, executions, webhooks, readiness, previews,\nreleases, replay, evidence, analytics, and improvements.\n\nProvider/webhook activation stays fail-closed unless callers pass approved\ntyped refs such as `provider_ref:*` and `webhook_ref:*`; raw `sk-*`,\n`whsec_*`, GitHub, Slack, or long secret-looking values return 422.\n\n## Auth, DB lifecycle, and RLS closure\n\nThe API monolith owns the executable Managed CompanyOS auth/database/RLS slice:\n\n- Session authority is request-derived from the `managed_companyos_session` cookie or the test-only `x-managed-companyos-session` header; invalid, missing, revoked, expired, or tenant-mismatched sessions fail closed.\n- Auth lifecycle state is exposed through API-local invitation, passkey, lockout, sign-out, and governed session-revoke routes. Invitation administration supports list, send, token-rotating resend, and terminal revoke; invitation and passkey routes return refs only, while raw passwords, public keys, provider tokens, and secret-manager URIs are rejected or kept out of responses. The seeded `/api/companyos/auth/test-login` helper is disabled outside test mode unless `MANAGED_COMPANYOS_ENABLE_TEST_LOGIN=1` is set.\n- The app Drizzle schema, migrations, local lifecycle, seed manifest, and mutation repository use canonical `managed_companyos_*` table names, including `managed_companyos_invitations`, `managed_companyos_passkeys`, `managed_companyos_passkey_challenges`, `managed_companyos_auth_lockouts`, and `managed_companyos_mutation_ledger`.\n- Drizzle schema code is the canonical source for feasible owned tenant RLS metadata. `src/db/schema.ts` attaches `pgPolicy` tenant-isolation policies to tenant-scoped Drizzle tables, while `src/db/rls-policy-inventory.ts` records executable SQL parity expectations, the explicit-`WITH CHECK` tenant policies, schema-only classifications and runtime descriptor fallback, and re-exports `src/db/rls-policy-inventory-exceptions.ts` (the 0066 topology evidence split, platform exceptions and the current Drizzle 0.x version gate: `pgPolicy` only; no `pgTable.withRLS`). Migration 0179 makes every inventory tenant policy compare `nullif(current_setting('app.tenant_id', true), '')`; 0183 validates its non-empty `CHECK` constraints.\n- Checked-in SQL migrations remain the executable artifacts. Before changing policy names, roles, `USING`, `WITH CHECK`, `ENABLE`, or `FORCE` semantics, run the ContractSpec Connect gate and the static parity tests; treat any table/policy/role SQL drift as compatibility-impacting unless explicitly classified in the plan/evidence bundle.\n- Local/test DB lifecycle commands require `MANAGED_COMPANYOS_TEST_DATABASE_URL` or `LSSM_STUDIO_TEST_DATABASE_URL` and refuse production-like targets. Reset removes every personal-context, team-grant, user-workspace-grant, personal-calendar, and briefing table before replay, so repeated reset/seed/bootstrap runs do not retain authority state. Auth lifecycle repository fallback to memory is test-only unless `MANAGED_COMPANYOS_ENABLE_MEMORY_AUTH_REPOSITORY=1` is explicitly set. When `AUTH_PROVIDER_MODE=better-auth`, the catch-all better-auth route also fails closed unless one of `MANAGED_COMPANYOS_AUTH_DATABASE_URL`, `MANAGED_COMPANYOS_TEST_DATABASE_URL`, `LSSM_STUDIO_TEST_DATABASE_URL`, or `LSSM_STUDIO_DATABASE_URL` is configured, preventing accidental in-memory auth fallback in production mode.\n- Live/shared DB lifecycle commands are separate:\n  `companyos:db:migrate:live`, `companyos:db:seed:live`, and\n  `companyos:db:verify:live`. They read `LSSM_STUDIO_DATABASE_URL` (or\n  `MANAGED_COMPANYOS_LIVE_DATABASE_URL`), emit only a redacted target\n  fingerprint, require approval evidence for all commands, require\n  backup/checkpoint evidence for migrate/seed, and expose no\n  reset/drop/truncate-all live action. Seed and verify accept no forward\n  tenant/workspace selector: one invocation reconciles the selected\n  contract-owned profile (`all`/`core-workspaces`: the live `lssm` and\n  `companyos` organizations) in deterministic order.\n  Each organization is atomic across its declared families, committed\n  organizations remain resumable after a later failure, and replay succeeds\n  only when receipt, expected counts, and the live semantic digest agree.\n  Optional hybrid booking is configured only through the fixed LSSM or\n  CompanyOS URL/evidence pairs documented in `deploy/env/api.env.example`.\n  Supplying only half a pair, a non-HTTPS/non-Calendly URL, or either legacy\n  singular selector fails before the seed opens its manifest-wide runner.\n  Receipts and command output expose only configured organization slugs and URL\n  digest evidence; they never emit the raw booking URL.\n- `companyos:db:prove-rls:test` verifies forced RLS metadata and SQL tenant-denial behavior when a permitted local/test DB URL exists. The proof provisions `managed_companyos_rls_proof_app`, queries `pg_roles`, and fails unless that role is `rolsuper=false` and `rolbypassrls=false`; tenant-denial assertions never run on a superuser or BYPASSRLS role. If no permitted URL is present, report the live proof as not run rather than passed.\n\n### AuthOS identity provider & identity-rbac authority\n\nWhen `AUTH_PROVIDER_MODE=better-auth`, the API serves a real AuthOS identity provider through the `@lssm-tech/integration.authos-better-auth` bridge (`src/auth/better-auth-setup.ts`). The runtime-backed login surface is email+password, email OTP, email magic link, and built-in social login for Google, Microsoft, LinkedIn, TikTok, Facebook, and GitHub. Verified aliases resolve to the same Better Auth user and shared password while OTP, magic-link, and recovery delivery uses the address entered. Public self-signup remains disabled by default; promotion requires every external evidence reference plus production Turnstile configuration. `GET /api/companyos/auth/login-methods` exposes only enabled method IDs, labels, and link requirements—never credentials.\n\nThe reviewed central LSSM identity profile is an isolated host deployment, not\na wider CompanyOS cookie mode. With `LSSM_IDP_ENABLED=1`, both auth and web\norigins must be exactly `https://id.lssm.co`, the cookie is host-only, and the\nOAuth 2.1/OIDC provider exposes standards-compatible discovery aliases. Product\napplications receive pairwise subjects and continue to own tenant, membership,\nrole, and data authority locally.\n\nLSSM OS is a separate relying party projected through this API. Reviewed\nactivation registers only `lssm-os-web`, the exact `app_lssm_os` scope, PKCE,\nand `https://os.lssm.tech/auth/callback/lssm`. The browser session remains an\nAPI-local `SameSite=None; Secure` cookie for `api.companyos.run`; it is not an\necosystem cookie. `os.lssm.tech` and `console.lssm.tech` enter the credentialed\nCORS allowlist only while that reviewed client is fully configured.\n\nThe product-access path is a separate fail-closed authority. Public intake is\nscoped to one registered application; opening the private status link proves\nemail possession and moves the request to review. Approval issues a 256-bit,\nsingle-use invitation whose plaintext exists only in email. Acceptance at\n`id.lssm.co/auth/accept-invite` provisions or reuses the central identity and\natomically records the active coarse entitlement plus redacted provisioning\nreceipts. The OAuth provider requests exactly one product scope and redirects to\n`/auth/access` unless that identity has an active, non-expired entitlement.\nMigration `0058_authos_product_access.sql` owns the durable event, invitation,\nentitlement, and receipt tables; replay is additive and tested with PGlite.\n\n- **Single-session authority.** Every credential path and enabled plugin funnels through `finalizeAuthenticatedSession` (`src/auth/active-org-hook.ts`). A preselected organization is preserved only after current membership validation. Otherwise, new-session selection uses the sole deterministic fallback `organization.created_at ASC, organization.id ASC`; no membership leaves the organization unset and downstream access fails closed.\n- **Fresh organization authority.** `activeOrganizationId` is an identity-plane key, not a physical tenant ID. Each protected request rechecks the current Better Auth session and membership, resolves an enabled organization-to-tenant binding plus canonical `managed_companyos_organization_grants` row, and derives the RLS tenant only from that verified binding. Global `user.role` and `managed_companyos_operators.role` remain compatibility/reporting projections and never authorize CompanyOS domain actions.\n- **Commit-time switch protection.** Resource transactions retain the expected session, organization, binding, and grant versions. Immediately before commit they lock and recheck the authoritative Better Auth session row and re-prove membership/binding/grant authority. A concurrent organization switch or authority change rolls the transaction back; callers must begin a fresh request rather than retrying under a newly selected organization.\n- **Fail-closed plugin config.** A capability marked `runtime-backed` in the spec without a real runtime-wired better-auth plugin throws at setup (`assertEnabledPluginRuntimeWiring` in `src/auth/plugin-config-guard.ts`) instead of silently no-opping.\n- **Provider tokens at rest.** Better Auth seals provider OAuth access and refresh tokens (`account.encryptOAuthTokens` plus a seal-on-refresh hook); legacy plaintext stays readable until it is rewritten, ID tokens are stored as received, and the deploy prerequisites, dual read and rollback rules live in `src/auth/oauth-token-encryption.ts`.\n- **Canonical grants feed identity-rbac.** The organization grant's validated role maps to the exact, least-privilege identity-rbac permission set in `src/middleware/companyos-role-permissions.ts`. `src/middleware/companyos-subject.ts` wraps `createSubjectProvider` (`@lssm-tech/lib.authos-runtime`) into the governance `Subject`, and `src/middleware/authorization.ts` attaches the resolved permission set to user actors. Control-plane/builder capability gating remains a separate axis; organization membership alone never grants domain, approval, billing, provider, or machine-only authority.\n- **401 vs 503 (retryable RBAC distinction).** No session → **401**. A *valid* session whose identity-rbac resolution fails (store transiently unavailable / unmapped role) → **503** with an `auth.rbac.unavailable` signal (hashed tenant, no PII/tokens), NEVER the 401 reserved for \"no session\".\n\n### Profile-aware bootstrap\n\n`MANAGED_COMPANYOS_SEED_PROFILE=core-workspaces bun run companyos:bootstrap-admin`\nreconciles the live LSSM and CompanyOS organizations for one canonical account;\n`all` selects the same live set. Live commands require an explicit profile and\nrefuse the deprecated reference-only `legacy-reference` profile because it\nincludes NDconsulting, decommissioned with Hirly on 2026-10-20 ([evidence](../../../docs/evidence/authos/decommission-hirly-ndconsulting-2026-10-20.md)).\nThe retired `lssm-hirly` profile is refused by every bootstrap and seed path,\nlocal included, and no `collaborators:hirly` phase runs; the company spec keeps\nthe id exported only as a deprecation window until its next major.\n\n- The bootstrap takes a session-scoped PostgreSQL advisory lock. Better Auth identity operations and tenant-scoped authority transactions are separate, idempotent saga phases; migration `0019` records each completed phase durably instead of claiming cross-connection atomicity.\n- Existing users never require or update a password. `BOOTSTRAP_ADMIN_PASSWORD` is read only when the configured admin account is absent; secrets and the admin email are not emitted in receipts or logs.\n- When Better Auth creates the absent user's primary email row first, bootstrap\n  verifies that same-user row in place and preserves its opaque provider ID.\n  A normalized email already owned by another user remains a hard conflict.\n- The canonical user has primary `tboutron@lssm.co`, verified alias\n  `theo@tryhirly.com`, and one private personal space. LSSM and CompanyOS bind\n  the primary owner email; Hirly, which bound the alias, was decommissioned on\n  2026-10-20.\n- Every selected organization has a distinct physical tenant/workspace binding\n  with only OPA and CommunicationOS enabled by default.\n- Replays are idempotent for the same profile and manifest revision. Email,\n  personal-space, membership-email, and module phases have durable receipts.\n\nMigration `0039` adds one-time, attempt-bounded alias verification challenges;\n`0040` adds owner-controlled join policies, verified-domain claims, and\ntransactional access-request decisions; `0041` adds retryable personal-context\nprovisioning state. Session creation never fails solely because private-space\nprovisioning is temporarily unavailable: the user remains authenticated and\ncan inspect `GET /api/companyos/personal-context/provisioning-status` before a\nbounded retry. Better Auth database lookups canonicalize verified aliases for\nOAuth callbacks without rewriting provider-account identity, so a verified\nsecondary email links to the existing user instead of creating a duplicate.\n\nAuthenticated profile, smart-meeting, booking-repair, approval, and Google\nCalendar routes verify the active workspace's OPA entitlement before touching\nOPA storage or provider runtimes. A disabled module is therefore hidden by the\nweb shell and denied independently at the API boundary.\n\nDeferred AuthOS capabilities (honest, contract-only with reasons — never marked runtime-backed):\n\n- `passkey` (WebAuthn): better-auth 1.6.15 ships no passkey plugin; requires `@simplewebauthn` + cross-package dep wiring — deferred to its own wave. (The app-local `managed_companyos_passkeys` ref routes above are a separate deterministic proof-path, not the better-auth WebAuthn plugin.)\n- `sso` / `saml` and `scim`: modeled as `external:*` bridge declarations (`runtimeWired: false`); ADR follow-ups pending real `@better-auth/sso` / `@better-auth/scim` wiring.\n- `audit`: Better Auth has no audit plugin; the API-owned `/api/companyos/auth/audit` projection reads the tenant RLS ledger, returns redacted classified events with signed pagination, and exposes a bounded administrator/auditor CSV export.\n- `connect-lssm-account-link`: the LSSM IdP (`oidc-provider`) is gated on `enableLssmIdp` + a security-review ref, neither configured in v1.\n\nLive DB operation checklist:\n\n1. Record the ContractSpec Connect gate/evidence for the migration/RLS decision.\n2. Put the live DB URL only in `LSSM_STUDIO_DATABASE_URL` or `MANAGED_COMPANYOS_LIVE_DATABASE_URL`; command output redacts URL user/password and records only a target fingerprint.\n3. Provide `MANAGED_COMPANYOS_LIVE_DB_APPROVAL_EVIDENCE_PATH` (or an opaque approval ref) for migrate/seed/verify.\n4. Provide `MANAGED_COMPANYOS_LIVE_DB_BACKUP_EVIDENCE_PATH` (or an opaque backup/checkpoint ref) before migrate/seed.\n5. Set `MANAGED_COMPANYOS_SEED_PROFILE`, run `companyos:bootstrap-admin`, and\n   require the complete selected authority manifest before business seeding.\n6. Run `companyos:db:seed:live` once for the selected contract-owned profile;\n   do not supply tenant/workspace selectors.\n7. Run `companyos:db:verify:live` and require exact family receipts, counts,\n   semantic digests, tenant isolation, and redacted evidence.\n8. Run only `companyos:db:migrate:live`, `companyos:db:seed:live`, and\n   `companyos:db:verify:live`; there is no live reset/drop/truncate-all command.\n9. Run static parity first: `bun test --cwd packages/apps/api-application-monolith src/db/schema.test.ts src/db/rls-policy-inventory.test.ts src/db/rls-proof.test.ts`.\n10. Run DB-gated migrate/seed/verify/prove commands only when the URL is\n    permitted.\n11. Report skipped or blocked DB proof as **not run**, never as passed.\n\nThe exact-head disposable PostgreSQL 15 proof creates two uniquely named\nloopback-only databases, compares empty migration with a production-through-0017\nforward replay, bootstraps the canonical organizations, forces and resumes a\nfamily failure, replays twice, verifies all families, and runs a cross-tenant\nSELECT/INSERT/UPDATE matrix as a real `NOSUPERUSER NOBYPASSRLS` role. It stops\nthe cluster, removes its temporary data, and proves the port is closed.\n\n## Integration Points\n\n### REST API Integration\n\nExternal systems integrate with Managed CompanyOS via REST routes:\n\n```bash\n# Workspace projection (workflow state, integrations, replay packets)\ncurl -H \"x-managed-companyos-session: <HMAC-signed-token>\" \\\n  https://api.host/api/companyos/workspace\n\n# Evidence verification (audit proof)\ncurl -H \"x-managed-companyos-session: <token>\" \\\n  https://api.host/api/companyos/evidence?correlationId=corr_xyz\n\n# Health check\ncurl https://api.host/api/companyos/health\n\n# Degraded health (returns 503 if API or scheduled snapshot duties are unhealthy)\ncurl https://api.host/api/companyos/health/degraded\n\n# Request-time Vercel snapshot readiness\ncurl -H \"x-managed-companyos-session: <token>\" \\\n  https://api.host/api/companyos/vercel/snapshot\n\n# Replay/evidence snapshot\ncurl -H \"x-managed-companyos-session: <token>\" \\\n  https://api.host/api/companyos/vercel/replay-evidence\n\n# Supervision-equivalent snapshot\ncurl -H \"x-managed-companyos-session: <token>\" \\\n  https://api.host/api/companyos/vercel/supervision\n```\n\nAll tenant-scoped queries derive `tenantId` from the verified session token. Cross-tenant access is rejected with 403.\n\n### MCP (Model Context Protocol) Integration\n\nFor AI agents and CLI tools, use the planned `@lssm-tech/app.managed-companyos-mcp` server (see `.omx/audits/mcos-mcp-design-20260515.md` for design).\n\nMCP tools expose the same operations as the REST API but with additional:\n- Tool context factory for tenant/actor/policy decisions\n- Resource URIs for replay packets, evidence receipts, and health snapshots\n- Prompts for copilot-style operator guidance\n\n### Manual refresh / snapshot integration\n\nWeb production should request snapshots from the API monolith and let users refresh or navigate to obtain a fresh request-time snapshot. Do not add WebSocket, SSE, EventSource, interval polling, or automatic polling as a replacement in the Vercel-only topology.\n\nThe standalone Bun realtime runtime remains documented in the worker package for non-production proofs and future VPS mode only; it is not a managed CompanyOS production dependency while this cost-capped Vercel topology is active.\n\nCentral governed-recovery bindings reuse the shared fail-closed HTTPS port from\n`@lssm-tech/lib.data-exchange-server`. Each product binding has one exact HTTPS\norigin and distinct server-only bearer; duplicate application bindings are\nrejected rather than overwritten. Revocation and rights requests omit worker\nlease metadata, ambient credentials, and redirects, and accept only bounded\nschema-valid product evidence.\n\n## Managed CompanyOS environment\n\nCopy `deploy/env/api.env.example` into the deployment secret-manager-backed\nenvironment group and apply the canonical environment contract in\n`docs/runbooks/managed-companyos.md`. Keep raw provider credentials out of\ncommitted files and evidence; concrete providers remain approval-gated.\n\nFor the managed monolith Vercel rollout, the supplied API DB URL belongs only in `LSSM_STUDIO_DATABASE_URL` and `MANAGED_COMPANYOS_AUTH_DATABASE_URL`. Do not copy it into the web app. `MANAGED_COMPANYOS_WAITLIST_DATABASE_URL` is optional and requires a separate low-privilege waitlist writer URL; leave it absent/empty otherwise. Using the same supplied API DB URL across production/preview/development and both API DB variables is an intentional blast radius only when all envs + migration were explicitly selected; split runtime, auth, migrator, and waitlist credentials later.\n\n| Variable | Purpose |\n| --- | --- |\n| `MANAGED_COMPANYOS_STATE_FILE` | Local/VPS preview only. Do not configure on Vercel; production state uses PostgreSQL. |\n| `CRON_SECRET` | Bearer secret used by Vercel Cron service-principal authorization. Required for scheduled snapshot, waitlist purge, channel dispatch, and connect-review sweep crons. |\n| `MANAGED_COMPANYOS_SESSION_SECRET` | **Required in production.** HMAC-HS256 signing secret for `x-managed-companyos-session` tokens. Must be a strong random value (≥32 bytes). Never commit to source control. |\n| `MANAGED_COMPANYOS_CONTEXT_AUTH_SECRET` | **Required for profile editing in production.** Distinct server-only HMAC key (≥32 bytes) that verifies web profile-context assertions. |\n| `MANAGED_COMPANYOS_DEFAULT_TENANT_ID` | Local/CI fixture fallback only. Leave empty in production; browser, query, and body tenant identifiers never authorize access. |\n| `MANAGED_COMPANYOS_ORG_AUTHORITY_CUTOVER` | Production authority selector. `1` requires verified organization membership, binding, grant, and organization-owned workspace scope. |\n| `MANAGED_COMPANYOS_PILOT_TENANT_ID` / `MANAGED_COMPANYOS_PILOT_WORKSPACE_ID` / `MANAGED_COMPANYOS_PILOT_SCENARIO_ID` | Exact legacy ND admission inputs during shadow/pre-cutover and for a rehearsed rollback build that requires cutover `0`; excluded from auth readiness and never forward authority. |\n| `MANAGED_COMPANYOS_REMOTE_CONFIG_URL` | **Required.** Signed tenant remote-config manifest URL for feature flags, runtime endpoints, and kill switches. Use `https://…` in deployment or `managed-companyos://fixture/<tenant>` in deterministic tests. |\n| `MANAGED_COMPANYOS_REMOTE_CONFIG_SIGNING_KEY_REF` | **Required.** Redacted key reference for remote-config manifest verification. Never commit raw signing material. |\n| `MANAGED_COMPANYOS_PROVIDER_APPROVAL_REQUIRED` | Must remain `true` until explicit provider approval exists. |\n| `LSSM_STUDIO_DATABASE_URL` | Shared managed CompanyOS PostgreSQL database used by the API and profile SEO. SEO assumes transaction-local NOINHERIT reader/builder roles; it does not require additional database URLs. |\n| `MANAGED_COMPANYOS_AUTH_DATABASE_URL` | Auth DB URL. May intentionally match `LSSM_STUDIO_DATABASE_URL` only for the approved all-env migrate rollout; prefer split credentials later. |\n| `LSSM_IDP_ENABLED` | Set to `1` only in the reviewed `id.lssm.co` deployment; omit elsewhere. |\n| `LSSM_IDP_SECURITY_REVIEW_REF` | Opaque approved security-review evidence reference required by the central identity profile. |\n| `LSSM_IDP_PAIRWISE_SECRET` | Secret-manager value of at least 32 characters used to derive pairwise relying-party subjects; never expose it to clients or logs. |\n| `LSSM_IDP_VALID_AUDIENCES` | Comma-separated exact HTTPS relying-party audience origins. Wildcards and an empty audience set fail closed. |\n| `LSSM_IDP_RP_RECONCILE_TOKEN` | Temporary 32+ character operator bearer for `POST /internal/authos/relying-parties/reconcile`. Configure only during a controlled client create/rotation ceremony, then remove and redeploy. |\n| `{HCIRCLE,PACTENA}_LSSM_RP_ENABLED` / `{HCIRCLE,PACTENA}_LSSM_RP_SECURITY_REVIEW_REF` / `{HCIRCLE,PACTENA}_LSSM_RP_CLIENT_SECRET` | Central IdP reconciliation inputs for the matching catalog client. Secrets are read only from the identity host environment and never accepted in the request. Remove the central client secret after the database reconciliation receipt is verified; the product API retains its matching runtime secret. |\n| `LSSM_IDP_LSSM_OS_RP_*` / `LSSM_OS_RP_*` | The `LSSM_IDP_` names are temporary central reconciliation bindings for the dedicated LSSM OS client; the unprefixed names belong only to the product runtime. Legacy central use of the unprefixed names remains compatible, but new ceremonies must use the explicit prefix so central readiness cannot confuse registration with product activation. |\n| `LSSM_GOVERNED_DATA_DATABASE_URL` | Central identity only: least-privilege forced-RLS runtime connection for governed projection grants, leased deliveries, rights jobs, revocation events, and acknowledgements. Run additive migrations separately; never supply a migrator/admin URL. The recovery console requires a fresh central `admin` session with verified MFA. |\n| `LSSM_GOVERNED_{HCIRCLE,PACTENA,COMPANYOS,LSSM_OS}_CATALOG_TOKEN` | Central identity only: distinct 32+ character product-service bearer for immutable projection and localized sharing-offer publication. Never reuse recovery, provisioning, or cron credentials. |\n| `LSSM_GOVERNED_{HCIRCLE,PACTENA,COMPANYOS,LSSM_OS,PERSONAL_OS}_RECOVERY_ORIGIN` | Central identity worker: exact HTTPS origin for a qualified product recovery ingress. Omit unqualified products. |\n| `LSSM_GOVERNED_{HCIRCLE,PACTENA,COMPANYOS,LSSM_OS,PERSONAL_OS}_RECOVERY_TOKEN` | Central identity worker: distinct 32+ character server-only bearer for the matching product. Never expose to web clients or reuse `CRON_SECRET`. |\n| `COMPANYOS_GOVERNED_DATA_DATABASE_URL` / `LSSM_OS_GOVERNED_DATA_DATABASE_URL` | Matching product API only: separate product-local forced-RLS encrypted-copy database. Never use the central grant database or a migrator connection at runtime. |\n| `COMPANYOS_GOVERNED_RECOVERY_TOKEN` / `LSSM_OS_GOVERNED_RECOVERY_TOKEN` | Matching product API only: distinct 32+ character recovery bearer. Database plus recovery bearer may be configured without enabling new materialization. |\n| `COMPANYOS_GOVERNED_DATA_REGION` / `LSSM_OS_GOVERNED_DATA_REGION` | Exact receiving-product residency region. Must be configured together with the matching materialization binding registry or startup fails closed. |\n| `COMPANYOS_GOVERNED_MATERIALIZATION_BINDINGS` / `LSSM_OS_GOVERNED_MATERIALIZATION_BINDINGS` | Secret-manager JSON array of exact `sourceApplicationId` and distinct 32+ character `bearerToken` pairs. Enables only `POST /internal/governed-data/materializations/:sourceApplicationId`; unknown/duplicate sources fail closed. Never use one ecosystem-wide token. |\n| `COMPANYOS_GOVERNED_DATA_AUTO_MIGRATE` / `LSSM_OS_GOVERNED_DATA_AUTO_MIGRATE` | Controlled activation only. Runtime defaults to no migration; apply additive schema with an approved migration owner first. |\n| `COMPANYOS_GOVERNED_DATA_SSL_MODE` / `LSSM_OS_GOVERNED_DATA_SSL_MODE` | `require` by default; `allow` or `prefer` only for a qualified local target. |\n| `LSSM_OS_RP_ENABLED` | Set to `1` only in the reviewed, dedicated `api.os.lssm.tech` deployment; it cannot share the CompanyOS RP deployment. |\n| `LSSM_OS_RP_SECURITY_REVIEW_REF` | Opaque approved security-review evidence required before the LSSM OS client or origins are exposed. |\n| `LSSM_OS_RP_CLIENT_SECRET` | Secret-manager value of at least 32 characters for `lssm-os-web`; never expose it as `NEXT_PUBLIC_*`. |\n| `LSSM_OS_MEMBERSHIP_PROVISION_TOKEN` | Dedicated 32+ character server-only token for idempotent central AuthOS → LSSM OS local membership provisioning. |\n| `LSSM_OS_MEMBERSHIP_PROVISION_URL` / `LSSM_OS_MEMBERSHIP_PROVISION_TOKEN` | Exact HTTPS LSSM OS receiver and matching central caller token. The receiver URL is `/internal/authos/product-memberships`; no query, fragment, or embedded credentials are accepted. |\n| `HCIRCLE_MEMBERSHIP_PROVISION_URL` / `HCIRCLE_MEMBERSHIP_PROVISION_TOKEN` | Exact HTTPS hCircle receiver and its independent 32+ character central caller token. |\n| `PACTENA_MEMBERSHIP_PROVISION_URL` / `PACTENA_MEMBERSHIP_PROVISION_TOKEN` | Exact HTTPS Pactena receiver and its independent 32+ character central caller token. |\n| `MANAGED_COMPANYOS_WAITLIST_DATABASE_URL` | Optional public waitlist writer URL. Must be separate and low-privilege; omit unless that credential exists. |\n| `MANAGED_COMPANYOS_BOOKING_GRANT_PEPPER` | **Required for the Postgres-backed booking provider-effect host.** Distinct server-only random pepper (≥32 bytes). |\n| `MANAGED_COMPANYOS_GOOGLE_CALENDAR_CLIENT_ID` / `MANAGED_COMPANYOS_GOOGLE_CALENDAR_CLIENT_SECRET` / `MANAGED_COMPANYOS_GOOGLE_CALENDAR_REDIRECT_URI` | Dedicated Google Workspace Calendar OAuth application. The exact HTTPS redirect is `/api/companyos/integrations/google-calendar/oauth/callback`; localhost is allowed only for local development. |\n| `MANAGED_COMPANYOS_BOOKING_QUEUE_URL` / `MANAGED_COMPANYOS_BOOKING_DELIVERY_SERVICE_URL` / `MANAGED_COMPANYOS_BOOKING_DELIVERY_SERVICE_TOKEN` | Optional external booking notification queue/service pair. Configure all three together; when the queue URL is omitted the calendar-maintenance cron uses the Postgres-durable direct relay. |\n| `OPA_PROFILE_SEO_MAX_PAGES` | Builder publication page gate, capped at 49,998. |\n| `OPA_PROFILE_SEO_MAX_BUILD_DURATION_MS` | Maximum authenticated repeatable-read build duration before rollback. |\n| `OPA_PROFILE_SEO_MAX_TOTAL_BYTES` | Maximum aggregate canonical page bytes before rollback. |\n| `OPA_PROFILE_SEO_MAX_PAGE_BYTES` | Maximum canonical bytes per page; must remain below 50 MiB. |\n| `POSTHOG_API_KEY` | Optional server-side PostHog key. The emitter is noop when unset. |\n| `POSTHOG_HOST` | PostHog server-side capture host. Use EU Cloud ingest `https://eu.i.posthog.com`. |\n| `MANAGED_COMPANYOS_MANAGED_REFERENCE_CREDENTIAL_REF` | Platform-managed reference-provider credential alias for the executable provider-neutral catalog. The value must be a redacted reference label/alias, not a raw key, webhook URL, bearer token, or secret-manager URI. |\n| `MANAGED_COMPANYOS_BYOK_REFERENCE_CREDENTIAL_REF` | Tenant-owned BYOK reference-provider credential alias for the executable provider-neutral catalog. The app stores and returns only redacted metadata. |\n| `MANAGED_COMPANYOS_MANAGED_<PROVIDER>_CREDENTIAL_REF` / `MANAGED_COMPANYOS_BYOK_<PROVIDER>_CREDENTIAL_REF` | Future provider-family env names for approved app/provider-layer adapters. Keep values in the deployment secret manager and pass only redacted aliases/metadata through API responses, logs, tests, and evidence. |\n\n\n### Provider strategy matrix\n\nThe executable app-layer provider catalog currently includes:\n\n- `managed-reference` → `reference-managed-channel`, configured by `MANAGED_COMPANYOS_MANAGED_REFERENCE_CREDENTIAL_REF`.\n- `byok-reference` → `reference-byok-channel`, configured by `MANAGED_COMPANYOS_BYOK_REFERENCE_CREDENTIAL_REF`.\n\nBoth entries expose redacted metadata only (`********`) and dispatch through an injected/provider-neutral harness. Missing env refs, raw-looking values (`sk-*`, `xox*`, bearer tokens, URLs/URIs, or oversized values), unknown provider ids, and unconfigured catalog entries fail closed before dispatch.\n\nThe broader provider family matrix is documented in `docs/runbooks/managed-companyos.md` and `specs/companyos-managed-readiness.md` as catalog/readiness intent, not blanket live-dispatch approval. Concrete SDK imports/defaults remain confined to app/integration/provider layers; lower bundles/libs/modules must stay provider-neutral.\n\n### Forms platform\n\nCompanyOS mounts management at `/companyos/forms`, public forms at\n`/f/{opaqueToken}`, and the API at `/api/forms/v1`. Configure\n`MANAGED_COMPANYOS_FORMS_DATA_PROTECTION_SECRET`, milestone flags, and optional\nverification, AI, and distributed-defense `MANAGED_COMPANYOS_FORMS_*` ports.\nMigrations `0048_forms_platform.sql` and `0050_forms_scope_hardening.sql` own\nthe product-local schema and its tenant/workspace/owner plus row-bound public\nRLS upgrade; creator scope is always derived from the resolved API session.\n\n### Governed meeting workspace\n\nMigration `0053` installs the OPA meeting-workspace forced-RLS tables. The\nadditive `0061` access-grant, `0063` provider-intake, and `0065` recurring\nintake-job migrations preserve the same five-axis owner scope. The\nElysia host mounts all nineteen exact catalog operations below `/api/v2/opa`\nusing the verified CompanyOS organization/workspace session, module\nentitlement, persisted capability grants, app-origin check, and CSRF session\nreference. Production initialization requires `LSSM_STUDIO_DATABASE_URL` plus\nthe versioned `OPA_BYOK_KEY_VERSION` and `OPA_BYOK_MASTER_KEY_<version>` secret;\nmissing storage or encryption configuration fails closed.\n\nThe provider-neutral transcript intake adapter is intentionally not an anonymous\nHTTP ingress. Its host caller must derive owner scope, active consent receipts,\nand recorder bindings from verified server state; normalized content remains\nunpublished until a credentialed provider integration earns its own transport\nand live qualification evidence.\n\n### OPA capture intake\n\nMigration 0075 adds owner-scoped consent receipts after encrypted staging 0074.\nThe seven declared capture routes are mounted under `/api/v2/opa`. Set\n`OPA_CAPTURE_ENABLED=1`, `OPA_CAPTURE_STORAGE_REGION=eu`, and the existing\n`OPA_BYOK_KEY_VERSION=v1` / `OPA_BYOK_MASTER_KEY_v1` secret to enable audio intake.\nEffective workspace grants must include `opa.recording.read`,\n`opa.recording.control`, and `opa.recording.consent_self`; existing grants are not\nimplicitly elevated. The meeting must already exist in the canonical workspace.\n\nConfiguration exposes the effective policy digest and consent notice version.\nGrant consent explicitly before creating a microphone/import session; submit\nsequential digest-bound base64 chunks of at most 1 MiB. Finish checks the announced\nchunk/byte totals and returns processing, never a fabricated transcript. Native\nbearer requests are freshly verified without a cookie fallback. Browser writes\nrequire the configured web origin and the current session CSRF token.\n\nProcessing availability is derived from the approved worker configuration and\ndispatcher credentials. Bot/system-audio/video intake remains unavailable in this\nhost. Worker deployment, device capture, cleanup and the full release evidence\nmust be qualified before rollout. Revocation, cancellation and deletion remain available when intake\nis switched off, subject to current membership and legal holds.\n\n### Scheduling effect authority\n\nApply additive migration 0076 before deploying the scheduling receipt producer.\nHuman calendar intents persist a policy-bound authorization receipt. Immediate\nexecution and cron retries reprove current session/membership/workspace, policy,\nWork placement, calendar write target and lease before provider credential lookup.\nPolicy changes invalidate queued approvals. Legacy pending commands require a\nfresh owner intent; historical applied effects are retained unchanged.\n\n`OPA_SCHEDULING_EFFECTS_DISABLED=1` stops every scheduling provider mutation.\nAutomation policy `disabled` stops new placement/movement while allowing an\notherwise-authorized owner cancellation. These are human-approved continuations;\ndelegated autopilot is not promoted by this change.\n\nMigration 0077 adds encrypted, owner-scoped transcript revision persistence after\n0076. It preserves existing artifacts and recordings. CompanyOS AI drafting rejects\ntranscript creation: use recorded/imported evidence through the transcription core.\nThe processing dispatcher and private transcript read route are mounted behind\nexplicit configuration. Transcript review and the remaining release gates are\nstill unqualified.\n\n### Durable capture processing\n\nMigration 0078 queues finalized captures and adds bounded worker admission plus\nrestricted dispatcher discovery. Configure a login whose current role is exactly\n`companyos_capture_dispatcher` in `MANAGED_COMPANYOS_CAPTURE_PROCESSING_DATABASE_URL`.\nThe role may call the due-scope function but cannot read media or transcripts.\nThe worker itself reads and writes captures on the restricted runtime login\n`companyos_capture_runtime` (migration 0181) in\n`MANAGED_COMPANYOS_CAPTURE_RUNTIME_DATABASE_URL`, never on\n`LSSM_STUDIO_DATABASE_URL`; the bot crons use `companyos_bot_runtime`\n(`MANAGED_COMPANYOS_BOT_RUNTIME_DATABASE_URL`) and recorder sync\n`companyos_recorder_runtime` (`MANAGED_COMPANYOS_RECORDER_RUNTIME_DATABASE_URL`).\nEach cron refuses any other `current_user`, a superuser, BYPASSRLS or an\n`opa_migrator` member (`CAPTURE_/BOT_/RECORDER_RUNTIME_ROLE_INVALID`).\n\nAutomatic capture processing is currently paused: the configured binding returns\nnull until Gateway EU transcription and speaker labels are qualified. Existing\nMistral credentials or capture flags cannot reactivate the default provider.\nThe cron at `/api/cron/opa-capture-processing` requires the exact `CRON_SECRET`\n(minimum 32 characters) and executes every minute with a 300-second budget.\n\nThe worker checks current recording-scope membership and consent independently\nof the active browser workspace. Transcript persistence and completion share one\ncommit. Cancellation/deletion invalidates queued work and releases capacity.\nThe existing transcript GET route exposes private segments and provenance; it\ndoes not approve a transcript or enable participant sharing. Review, participant\nconsent integration and the broader production gates remain incomplete.\n\nTranscription model choice (`opa.transcription.settings.get|save`, migration\n0161) is stored per user and per workspace (workspace default for workspace\nadministrators) at `/api/companyos/opa/transcription/settings`; the cron worker\nresolves each capture owner's choice, and only EU-qualified catalog ids are ever\nforwarded. While the catalog is empty the settings report `no_eu_model`.\nDeleting a capture with `deleteDerivedOutcomes: true` also erases, in the same\ntransaction, the unpublished and unshared drafts, outcomes and context derived\nfrom its transcripts (aggregate plus the append-only projections through the\n0162 owner-bounded definer function `opa_erase_derived_meeting_records`),\ncancels their outcome jobs, keeps published or shared notes and writes an\n`opa.capture.derived_outcomes_deleted` audit event with counts only.\n\n### Transcript review\n\nMigration 0079 enables encrypted source-bound review history. POST the existing\ntranscript review route with its 3.0.0 input: exact transcriptRef, artifactDigest,\nexpectedRevision and expectedReviewRevision. A missing review has revision zero.\nThe route requires current private read and review permissions and native bearer\nor browser origin/CSRF authority. Source changes never inherit an old approval.\n\nReviewed replacement text is a separate encrypted copy; original timed segments\nremain unchanged and are omitted from the reviewed-copy projection. Parent\ndeletion erases replacement content. The UI's canReview flag is presentation,\nnot execution authority. Review alone does not send or commit any outcome.\n\n### Private reviewed meeting outcomes\n\nThe existing meeting-workspace routes accept `x-opa-owner-view: private` to derive individual ownership from the verified user within the selected workspace. Omitting the header preserves context ownership; arbitrary owner selectors are rejected. Use the same private view for outcome analysis and subsequent artifact reads. The web BFF forwards this selector after its existing authentication and mutation-origin checks.\n\nCompanyOS outcome analysis loads the persisted approved transcript review, verifies exact source and review bindings, and checks current `intelligence.generate` policy before generation and commit. Rejected, changed, unauthorized or workspace-widened sources fail closed. The adapter uses the caller transaction and does not publish private capture text. Model calls run outside aggregate transactions. Finalization reloads current state and rechecks authority and the reviewed source before saving. Durable outcome jobs are available behind explicit configuration; downstream effects and live quality qualification remain open.\n\n### Reviewed outcome drafts in CompanyOS\n\nThe approved transcript panel can generate and read private meeting drafts through existing OPA operations. Generation controls use server-derived `canGenerateOutcomes`; authority and automation policy are rechecked server-side. Draft generation creates no messages or Work tasks. French, English and Spanish copy distinguishes loading, generation, retry, denied access and empty history.\n\nArtifact list 2.2.0 accepts optional `reviewRef`, selecting the current review before source reproof so stale historical drafts do not block current results. Transcript get 2.2.0 adds the generation capability projection. The client pins private ownership and an exact review-derived retry key, including across reloads. Interactive generation has a bounded 180-second request deadline; the web proxy allows a 300-second function budget. Persisted background jobs, signed-native presentation and full browser/accessibility qualification remain incomplete.\n\n### Correcting and reviewing outcome drafts\n\nArtifact review 3.0.0 accepts optional `editedContentMarkdown` when approving. The request still binds the displayed artifact revision and original content digest; the receipt approves the corrected digest. Human edit metadata records the prior digest, actor and timestamp. Empty edits, edits combined with rejection/CRDT snapshots, and independent edits during open collaborative sessions are rejected. A retry key cannot approve a different payload.\n\nThe private draft cards expose edit, approve and needs-changes controls using server-derived `canReviewOutcomes`. Uncertain review responses retain the current draft for retry; access denial removes it. Approval does not send messages, publish links or create Work tasks. Actual edited-review PostgreSQL qualification, complete collaborative editing and downstream actions remain open.\n\n### Durable outcome processing\n\nAnalyze 3.1.0 accepts `executionMode: background` on its existing route. Repeating the exact request observes the same persisted job; processing responses carry `processingJobRef`, while completion returns the saved outcome. The private draft client selects background mode when the server advertises it and can stop polling without cancelling accepted work. Terminal failures remain failures.\n\nApply additive migration 0080, configure a dedicated `companyos_outcome_dispatcher` login, and enable `OPA_OUTCOME_JOBS_ENABLED=1` only with approved pinned `OPA_MEETING_AI_*` EU processing. The every-minute `/api/cron/opa-outcome-processing` route requires `CRON_SECRET`. Runtime credentials must not be superuser, BYPASSRLS or a member of `opa_migrator`. The queue admits four global jobs and one per owner, bounds pending owner jobs at 25, retries at most five times and uses six-minute fenced leases. Current membership, module entitlement, intelligence policy, source consent/review and model binding are rechecked before generation and commit.\n\n### Meeting follow-up effects cron\n\n`/api/cron/opa-meeting-effects` (every minute, `CRON_SECRET`) hosts the meeting\neffect worker cycle in process, so approved follow-ups deliver without a separate\nworker host. Apply additive migration 0172 and give `companyos_meeting_effect_dispatcher`\na login in `MANAGED_COMPANYOS_MEETING_EFFECTS_DATABASE_URL`; that role can only call\n`companyos_meeting_effect_due_scopes`, which returns owner scopes, never effect refs or\ncontent. Claims, authority reproof, rollout, approval and artifact-digest checks, the\nPostgres dispatch fence, delivery and settlement run as the RLS-bound runtime role\n(`LSSM_STUDIO_DATABASE_URL`, never superuser, BYPASSRLS or `opa_migrator`) on a pool\nopened per invocation. Switches: `OPA_MEETING_EFFECTS_CRON_ENABLED=1` and\n`OPA_MEETING_FOLLOWUP_DELIVERY_ENABLED=1`; `OPA_MEETING_FOLLOWUP_TARGETS` and a strict\n`companyos` entry in `OPA_MEETING_EFFECT_ROLLOUTS_JSON` are required. Off or\nunprovisioned answers 200 with `stoppedBy` and variable names only. Each invocation\nhandles at most 10 owner scopes, 3 leases per scope and a 60 s budget; the log line\n`opa_meeting_effects_cycle` carries counts and failure codes only. Run exactly one\neffect host per database: this cron or `@lssm-tech/app.meeting-effect-worker`.\n\nThe `verified_email` target routes the reserved recipient `owner:self` to an owner-only\nrecap: the approved follow-up or summary goes to the approving owner's primary verified\naccount address (individual owner scopes only) through the CompanyOS Briefings Resend\nmailbox, keyed by the effect for provider deduplication. It is off unless\n`OPA_MEETING_FOLLOWUP_OWNER_RECAP_ENABLED=1` and `RESEND_API_KEY` are set.\n\nAttendee refs on `verified_email` and every `communicationos_thread` effect go\nthrough CommunicationOS, composed per delivery inside the owner transaction:\n\n- **Authority.** The server-side `createCommunicationOsAuthorityIssuerV1` issues\n  the Runtime V3 order only for the one send that delivery describes, after\n  the delivery service has re-proved the plan approval, the approver and their\n  dispatch capability. The approval port recomputes that request itself (bound\n  scope, `production` environment, effect, channel, effect-bound idempotency\n  key, and the approved context digest over the room in `threadRef`, the\n  address the approved recipient ref resolves to, the re-proved artifact\n  content and the bound principal); the room is the adapter's per-delivery\n  room, bound through that digest. The order's authorization digest commits to\n  the approval evidence. Thread refs use `communicationOsRoomThreadRefV1`\n  (`communication-room:<base64url(roomId)>`), unlike the calendar briefing\n  path, which still sends the raw room id.\n  `OPA_MEETING_FOLLOWUP_COMMUNICATION_AUTHORITY_JSON` carries the operator\n  deployment (Runtime Node, provider binding, queue profile, TTL); unset or\n  invalid keeps both targets `adapter_unavailable`, and an invalid value logs\n  `OPA_MEETING_FOLLOWUP_COMMUNICATION_AUTHORITY_INVALID` (code only).\n- **Durable record.** The admission is deferred to the caller: an email's\n  operation, order, runtime outbox and envelope refs go into its\n  CommunicationOS outbox row, a thread post's into its message event metadata.\n  An explicit authority denial or queue refusal dead-letters the effect; an\n  unavailable approval, a packet mismatch or an outage retries.\n- **Binding.** Only an individual CompanyOS owner scope approved by that owner\n  binds, to the owner's enabled personal CommunicationOS context as `user:<id>`.\n  Team and workspace scopes stay `adapter_unavailable`.\n- **Recipients.** A `participant:<directory>:<subject>` ref resolves only when its\n  owner-salted subject matches exactly one attendee address of that meeting,\n  read live from the owner's calendar (OPA stores no address) once per\n  delivery and bounded to 10 s (a timeout answers 503 and retries). Named\n  attendees resolve once the meeting event reader keeps provider addresses;\n  until then only e-mail-shaped attendee labels do.\n- **Store and connections.** The journal and outbox use the effect host's own\n  pool (the `companyos_opa_runtime` login in the cron), never a pool on\n  `LSSM_STUDIO_DATABASE_URL`. A delivery holds its owner transaction while it\n  reads attendees and writes CommunicationOS, so it needs at least two more\n  connections of that pool. No migration grants the cron login membership in\n  `communication_os_app` yet (without it delivery fails and retries); an\n  operator migration must add it. The login must also hold `execute` on\n  `managed_companyos_resolve_personal_context(text)` (0173) and `select` on the\n  attendee read's tables (`managed_companyos_personal_briefing_preferences`,\n  `managed_companyos_personal_contexts`, the personal calendar sources,\n  selections and workspace mappings, `managed_companyos_user_workspace_grants`,\n  `managed_companyos_workspaces`, `opa_calendar_connections`,\n  `managed_auth_email_addresses` through 0182). Google calendar reads use the\n  Google calendar runtime's own pool.\n\nThe email is queued in the CommunicationOS outbox; the CommunicationOS worker\nand Agent Host send it with the\n`env://COMMUNICATION_OS_CONNECTION_OPA_MEETING_FOLLOWUP_RESEND` credential,\nbefore its order expires (deployment `ttlSeconds`, at most 900 s). The effect\nalready counts as delivered, so an expired order must be re-admitted on the\nCommunicationOS side, not by an OPA retry.\n\nOutcome persistence and completion share a transaction; model calls are outside SQL. Queue rows contain references and authorization evidence, not transcript text or credentials. Model cost may repeat after a crash before commit. Terminal-job self-service repair, queue retention/deletion propagation, live model/provider qualification and production rollout remain open. No production activation is implied by the local tests.\n\n### Work commit authority for OPA follow-through\n\nManaged Work mutations now resolve canonical identity, read projections, persist the event/idempotency/outbox, and reprove authority within one outer transaction. The existing verified operator binding is preserved. Current organization, session, workspace and applicable team grants are locked before the effect and checked again before commit. A final denial rolls back all Work writes.\n\nThe HTTP mutation route uses the shared verified-bearer resolver, rejects cookie fallback when authorization is present, and requires exact origin/CSRF for browser requests. Bodies are bounded to 1,100,000 bytes. Read-only and suggest-only labels cannot authorize mutation; approval-required and reserved actions remain unavailable until their approval verifier is composed. Errors are content-free and not cached. This is the commit foundation; approved OPA action projection and CommunicationOS delivery still require their explicit adapters.\n\n### Canonical Work hierarchy and legacy parity\n\nApply additive migration 0081 after 0080 before enabling new Work identity allocation. New operators reuse canonical tenant/organization/workspace IDs for the same verified legacy scope, and a principal retains its canonical ID across workspaces within a tenant. The database enforces this during mixed-version rollout; new allocation is serialized per legacy tenant. Existing bindings are read without taking the allocation lock.\n\nExisting rows and Work events remain intact. A coherent legacy mapping is adopted for new operators; conflicting parent or principal mappings block new allocation with `WORK_IDENTITY_RECONCILIATION_REQUIRED`. Use `inspectWorkIdentityParity` inside an authorized transaction with the physical tenant GUC set to inventory conflicts. It reports scope categories and counts without rewriting data. Do not pick an arbitrary legacy ID or rewrite immutable Work events to clear the error. A reviewed reconciliation and parity/restore proof are required before enabling shared projection for a conflicted tenant.\n\nThe preparation function rejects foreign scope or unavailable trigger enforcement. Personal-context provisioning uses distinct physical tenants/workspaces, which remain isolated. This change is locally verified on PostgreSQL 15; production migration and existing-data reconciliation remain separate release gates.\n\n### Evidence-bound action proposals\n\nMeeting prompt 2.0.0 requires structured `actions` for action-plan generation. Each proposal carries a title, optional description, explicit/uncertain classification and exact quotations tied to supplied citation references. Missing action output or unsupported quotes fails generation. Model output cannot supply owners or deadlines. Quote membership proves traceability, not semantic correctness.\n\nAction-plan artifacts retain `actionProposals`, and their content digest covers prose and structured actions together. Artifact review 3.1.0 requires `acknowledgeActions` for a nonempty task list. Reviewers may edit titles/details while preserving verifiable source evidence. The private draft cards display proposed tasks, uncertainty and source quotes with an explicit approve-draft-and-tasks label. Prose-only or collaborative edits clear stale structured actions; edited structured input is revalidated against the current approved transcript.\n\nThis creates reviewed proposals, not Work commitments. Assignment, due dates, canonical Work projection, downstream delivery, deletion propagation and the live precision/recall benchmark remain open. Prompt-version changes invalidate incompatible queued generation bindings; never relabel old processing as using the new prompt.\n\n### Approved action to canonical Work\n\n`opa.task.project` 3.0.0 projects one approved structured action through the existing task route. The request binds artifact revision/digest, approval receipt, action reference and selected workspace. It requires explicit workspace disclosure acknowledgment and confirmation for an uncertain proposal. The UI exposes this action only for approved task lists and server-derived projection permission.\n\nOnly the reviewed title and details are transferred; raw/private transcript text and source quotes are not copied into Work. Assignees and deadlines remain unset. Current `outcome.commit` policy, transcript review/consent and Work workspace write authority are rechecked. Work event/idempotency/outbox and the OPA projection receipt commit in one transaction. Repeated projection returns the existing Work object; a receipt represents committed task creation, not task completion or realtime projection convergence.\n\nNew owner capability manifests include `opa.task.project`; existing grants require an authorized update and are not silently widened. Legacy input-only projection clients must update to 3.0.0. CommunicationOS delivery, assignment/due-date controls, real-authority deployment qualification and full release gates remain open.\n\n### Native meeting mutation authority\n\nOPA meeting workspace routes use bearer-only session verification whenever Authorization is present. Cookies and test-session headers are stripped before bearer verification; invalid tokens cannot borrow browser authority. Verified bearer POST requests need no fabricated Origin or CSRF. Browser POST requests retain exact origin and current session CSRF checks. Entitlements and current domain authority remain mandatory.\n\nOnly GET/POST are accepted, and mutation bodies are streaming-bounded to 1,100,000 bytes even without Content-Length. The CommunicationOS native-session exchange uses the same isolated bearer resolver. Route tests do not qualify signed native clients, MFA/deep links, capture permissions or app-store acceptance.\n\n\nMigration 0082 adds immutable owner-scoped legacy-to-canonical meeting bindings. The default-off legacy diagnostic probe now uses persisted mappings with current CompanyOS authority reproof; missing mappings cannot initialize synthetic workspaces. This integration only reads mappings. A verified backfill and current workflow parity evidence are required before any legacy route cutover; no production data is reset or automatically rebound.\n\n\n### Private meeting preparation context\n\nCompanyOS graph context now requires a verified individual, an exact five-axis `meetingContextOwnerScope`, the selected `meetingRef`, explicit bounded `meetingContext` text, and declared `meetingContextClaimKind` and `meetingContextSensitivity`. Inferences require confidence; estimates also require calculation/expiry timestamps. Generic titles/summaries and unscoped legacy projections are omitted. Append new validated graph projections through the existing Company Intelligence repository; do not rewrite append-only rows to infer missing bindings.\n\nReads run in a physical-tenant transaction. Every citation must resolve to current, non-superseded evidence and a fragment in the authorized workspace or principal ownership, with a current explicit principal ACL. Revocation tombstones invalidate their superseded sources. Graph payload audience flags and consent strings cannot authorize sharing: this source returns private context only. Generation compares every claim and source revision with a fresh authorized read before model invocation and before accepting the result. Historical artifact erasure and verified participant-sharing sources remain separate release requirements.\n\nPrivate OPA route families now support exact trusted-origin credentialed browser CORS, using the existing AuthOS trusted-origin configuration. Preflight accepts only the declared methods/headers, including `x-opa-owner-view` and `x-csrf-token`; endpoint authentication and mutation checks remain mandatory. Public booking/embed transport is independent. Background preparation without a verified principal/source workspace remains unavailable; a database-ready worker alone is not source or workflow qualification.\n\n\n### Durable private meeting creation\n\n`GET /api/v2/opa/meeting-creation-context` returns the current private owner-scope digest and remaining meeting capacity. `POST /api/v2/opa/private-meetings` accepts `request.expectedOwnerScopeDigest` and a stable `request.idempotencyKey`. Both operations require current `opa.meeting_work_session.manage` authority. The digest is a workspace-change guard, not an authorization token.\n\nCreation atomically saves the encrypted workspace aggregate, lookup projection and replay receipt, with current authority checks before and after writes. It creates no calendar event, booking, recording or consent. Exact replays remain valid at the 10,000-meeting per-owner bound. Native bearer requests use the existing MFA-safe mutation resolver; cookie mutations retain origin and CSRF checks. Capture lookup accepts either the current user's persisted private meeting or the selected authorized shared meeting and restores private scope afterward.\n\nThese two CompanyOS routes are additive to the unchanged nineteen-operation generic meeting service group. They use existing workspace persistence; no new migration or data reset is required. Existing read-only workspace materialization remains non-persistent and now carries a valid policy digest.\n\n\n### Preparation transaction boundaries\n\nCompanyOS preparation model calls now run outside workspace database transactions. Initial and final phases check current authority, explicit AI policy and context; source validation reuses the caller transaction and restores the OPA owner GUCs after the CI read. Finalization reloads the aggregate, preserves unrelated writes and commits drafts plus replay state atomically. Cached requests remain authorized and cannot change the requested artifact sequence.\n\nReviewed outcome generation uses its own draft generator inside the existing transcript-review and job-authority orchestration. It no longer requires unrelated graph-context projections. Source/member revocation and cancellation continue to fence outcome finalization. Model calls in these tests were controlled ports; live model quality and full load qualification remain open.\n\n\nCompanyOS preparation generation now requires additive migration `0083` before deploying this runtime. `SqlPreparationAdmissionStore` admits one active model request per complete owner scope, using six-minute database-clock leases and at most five attempts per request. Immutable digests bind the request key to its exact input, context and policy; conflicting reuse fails. Concurrent requests receive the existing `IDEMPOTENCY_IN_PROGRESS` error and may retry the same key. Expired workers cannot commit artifacts or release a replacement worker's lease. Admission completion and artifact persistence share one transaction. Cached artifacts still require fresh authority and source checks. Crashes may repeat model cost after lease expiry; this does not establish global model quotas, background preparation qualification or live-provider acceptance.\n\n\n`GET /api/companyos/work/objects/:objectId` reads a canonical UUIDv7 Work object under current server-derived workspace authority. The request accepts no scope parameters. Existing coherent canonical workspace mappings are read without allocation; conflicting mappings fail closed. The API uses the scoped, event-head-aware Work store and reproves read authority before returning. Responses are private/no-store, and absent, foreign or archived objects return not found. Native task-detail presentation is separate qualification work.\n\n\nPOST `/api/companyos/work/objects/:objectId/status` accepts only a canonical object ID, expected revision, status category and idempotency key. Current writable authority and actor/scope are derived server-side inside the transaction. The existing Work service commits status changes and three outbox destinations atomically. Completion uses server time; reopening clears completion time. Identical retries resolve the stored event before current-state validation. Native controls and live end-to-end qualification remain open.\n\n\nWork task detail now exposes canonical status choices when the authenticated read projection supplies `canUpdateStatus`. Missing permission is read-only. Native updates bind the displayed revision and reuse the same request key for an uncertain retry of the same status. Verified event identity, next revision, status and original workspace scope are required before reloading the task. Session invalidation and blur abort the client request without claiming to undo a possible server commit. Signed-device completion/reopening acceptance remains open.\n\n\n`createCompanyBotWebhookIntake` composes host-selected owner/deployment/secret resolution, bounded raw UTF-8 signature verification and atomic bound-bot settlement. It returns acceptance only after settlement commits and preserves replay acknowledgments. No public route is mounted by this helper: a durable route registry and domain lifecycle/outbox apply handler are mandatory before enabling bot callbacks. Payload tenant fields cannot select authority.\n\n\nBot webhook raw-body intake enforces a ten-second total read deadline in addition to the one-megabyte bound. Aborted, oversized and stalled streams are cancelled without awaiting their cancellation callback. Fatal UTF-8 decoding still preserves exact valid signed text across chunk boundaries. Timeout never acknowledges callback acceptance.\n\n\nBot reconciliation uses additive migration 0084 and a coalescing owner-scoped request row. Verified callback intake defaults to enqueueing reconciliation in its receipt transaction, rather than applying delayed provider state. Workers claim three-minute leases, one active per owner, with five failed attempts and a retry delay. New notifications during a lease remain queued after completion; expired/replaced workers cannot settle. More notifications cannot revive an exhausted job. The provider-fetch worker, repair UI and deployment dispatcher still require integration; do not activate callback routes before migration and host wiring.\n\n\nConfirmed bot bindings may retain the existing capture authorization context inside their encrypted payload. CompanyOS `guardCompanyBotCapture` requires this context, the bot capture enable flag, current background membership/policy digests, the exact active bot capture, unexpired retention, consent and current meeting access. It reuses the existing background authority resolver rather than browser session state. Legacy bindings without context remain readable identity evidence but cannot execute background bot work. Concrete dispatcher/provider wiring and cleanup authority remain separate integration requirements.\n\n\n`createCompanyBotProviderRead` supplies the reconciliation worker's concrete Attendee read adapter. It resolves configuration by the encrypted binding's deployment reference and checks lease, immutable bot identity and CompanyOS capture authority before secrets and again immediately before HTTP dispatch. Cancellation is forwarded and provider I/O remains outside SQL. Hosts must supply the deployment registry and queue/binding stores; no production dispatcher is enabled by importing the factory.\n\n\nCompanyOS deployment resolution now permits existing-bot reads only for active or draining configurations. It captures the encrypted registry revision, lazily resolves the owner-scoped API secret, and rechecks configuration before secret access and again before HTTP dispatch. Disabling or rotating configuration invalidates pending reads. `SqlBotDeploymentStore.readInTransaction` reuses the effect-authority transaction without acquiring another connection. Administrative UI, concrete secret-store binding, bot starts, global scheduling and live provider qualification remain open.\n\nPrivate meeting creation uses `createCompanyPrivateMeetingAuthority` for the existing individual owner scope, capability checks and transaction-bound membership reproof. Capture authority delegates the same checks and retains its additional consent/policy/source enforcement. The web private-meeting entry requires creation-context, creation, authorized workspace and artifact-list reads to be deployed together; creation alone does not provide recording or editable meeting notes.\n\n## Private meeting notes\n\nCompanyOS exposes one private human-authored notes draft per meeting through additive `opa.meeting_artifact.get_note` and `opa.meeting_artifact.save_note` operations at `GET/POST /api/v2/opa/smart-meetings/:meetingRef/notes`. Existing meeting-work-session management permission authorizes this personal authoring surface; recording, transcript generation and model credentials are not prerequisites. Saves use `expectedRevision` (zero for creation), at most 100000 characters and a stable idempotency key. Notes remain `live_notes/private_user/draft`, persisted in the existing encrypted aggregate. Empty content clears the draft. Revision conflicts preserve the local draft and show the latest saved notes before an explicit choice to continue. Saving notes creates no Work task and sends no message.\n\nThe Work-to-OPA planning loader must assemble each task’s dependencies from the latest relationship state across all aggregates in the exact tenant/organization/workspace scope. Both outgoing `blocked_by` and incoming `blocks` edges are prerequisites under the existing Work projection contract. Filtering which tasks can be placed must not erase dependency edges from other Work aggregates. This is a loader correctness invariant; it does not activate the background outbox reoptimizer.\n\nWork planning now uses `loadSnapshot(scope)` to obtain placement candidates and `completedWork` references from one scoped event replay. Completed prerequisites remain valid even without estimates or selection for personal placement. `loadWork(scope)` remains compatible for older callers. Reopening removes completion truth; no estimated duration is fabricated. Interactive proposal digests include completion revisions.\n\n\nOPA direct workspace authority binds four contiguous SQL parameters; team authority binds five. An unused null parameter in the direct-grant query previously caused PostgreSQL 42P18 and made private meeting readiness unavailable. Current membership, workspace scope, grants and revocation checks remain mandatory. The regression executes the exact workspace query through the production PostgreSQL driver.\n\n`WorkProposalPersistence` is a preparatory proposals-only publisher for future Work-outbox reoptimization. It uses existing personal plan ownership and canonical Work plan envelopes, requires transaction-local full-owner/lease/current-policy guards both before effects and before commit, and leaves placement/calendar tables untouched. Its guard bindings and dispatcher activation are still unimplemented; constructing the seam is not proof of active background planning.\n\n\nPrivate meeting failure diagnostics record only the operation, processing stage, an allowlisted error class and a five-character SQLSTATE. Error messages, SQL text/parameters, note content and credentials are excluded. Disabled OPA workspace modules return the declared FORBIDDEN response rather than being disguised as service unavailability.\n\nCapture processing must resolve meeting access using the same private-first rule as interactive capture: check the captured individual’s private meeting, then the currently authorized workspace/team meeting. Background company context must not make a private meeting disappear. Every fallback restores the complete capture owner scope and retains authority, consent, policy and lease checks.\n\n### Explicit regional processing endpoints\n\nNew AI/outcome configuration requires the exact Gateway origin with geography\n`other`, explicit `eu` provider inference and separate global-transit approval.\nThe configured model/provider allowlist, no-training and retention restrictions\nremain mandatory. The host rechecks the binding before transport and accepts\nonly matching EU response evidence. Capture transcription has no active default\nprovider while EU speaker-labelled Gateway processing remains unqualified.\n\nHistorical endpoint-bound artifacts remain readable, including explicit\nMistral EU/EFTA test fixtures. They do not activate a live provider, and no\nhistorical record or queued approval is rewritten. Storage placement and\nprovider inference/transit are independent qualification requirements.\n\nThe CompanyOS calendar-intelligence host omits direct-Mistral credentials and model\nselection, even when the old environment variables remain present. It composes\nlocalized deterministic-v2 recaps/briefs and records deterministic fallback status.\nCalendar reads, booking maintenance and delivery authority are unchanged. Gateway\nis not wired into this calendar path yet; see `docs/runbooks/companyos-briefings-v2.md`.\n\n## Meeting AI through Vercel Gateway\n\nNew production meeting generation uses `OPA_MEETING_AI_PROVIDER=vercel-ai-gateway` with `OPA_MEETING_AI_ENABLED=1`, a pinned `OPA_MEETING_AI_MODEL`, exact `OPA_MEETING_AI_ENDPOINT_ORIGIN=https://ai-gateway.vercel.sh`, `OPA_MEETING_AI_REGION=eu`, `OPA_MEETING_AI_PROCESSING_APPROVAL_REF`, `OPA_MEETING_AI_GATEWAY_TRANSIT_APPROVAL_REF`, and one approved non-Mistral `OPA_MEETING_AI_GATEWAY_PROVIDER`. Credentials come from `AI_GATEWAY_API_KEY` or existing `VERCEL_OIDC_TOKEN`; no Mistral key/default fallback is read. Outcome jobs additionally require their existing enable switch. References must correspond to actual approved processing/transit decisions before activation.\n\nGateway transit is recorded as geography `other`, separately from EU inference. Exact binding checks run immediately before transport and after generation. Returned routing metadata must prove the served provider appears among the approved EU attempts; request flags alone are insufficient. Existing private/shared context filtering and cited outcome validation remain enforced.\n\nAutomatic capture transcription is temporarily unavailable: `eu_transcription_not_qualified` and `speaker_labels_not_supported`. Its binding returns typed null and its default worker rejects with `CAPTURE_PROCESSING_UNAVAILABLE`; legacy Mistral credentials/flags cannot reactivate it. Existing records and controlled test ports remain intact. Qualify actual Gateway speaker-labelled EU transcription before changing this boundary.\n\nCompanyOS uses one processing-readiness predicate for the capture configuration view and new-session admission. New captures check readiness before insertion and before commit. Exact authorized create retries bypass new-session admission; existing media can still be uploaded and recovered under current consent, policy and source controls. An unavailable processor does not silently collect new recordings.\n\nGateway EU response evidence accepts both zone and specific endpoint scopes only when geoRegion is explicitly eu. A more specific EU endpoint is not a global fallback. Missing/global/non-EU evidence remains rejected; requested routing flags alone never prove the served geography. This does not grant private Gateway transit approval.\n\nWork proposal publication v2 carries the exact outbox delivery attempt. Its default SQL lease guard locks the current leased Work record and checks destination, full event, owner, attempt and expiry using database time. It restores the prior tenant context on success or failure. Owner mapping and effective policy guards remain mandatory; the dispatcher is not activated by this binding. Existing valid replay does not write calendar placements or effects.\n\nThe shared OPA background authority resolver now supports planning.propose with the exact opa.plan_run.manage capability, alongside existing capture and intelligence actions. It uses current locked organization/workspace/team grants and module entitlement, independently of browser-session lifetime. It returns the resolved policy mode and digests; callers must separately enforce manual/approval/delegation semantics. The capture-named export remains a compatibility alias. No planner dispatcher is enabled by this extraction.\n\n`loadWorkProposalOwner` resolves existing selected-workspace and personal-owner authority, locks the canonical Work mapping for the production user identity, and produces a combined authority digest plus both policy modes. It allocates no identities and grants no execution authority. All six SQL owner-context settings are restored, or rolled back with an aborted transaction. Work source/input revision proof and the policy-aware dispatcher still require composition.\n\nWorkspace revision fencing hashes every canonical Work aggregate head, including unplaced, completed and archived work. Work commits take a shared workspace advisory lock; proposal publication takes its exclusive counterpart and checks the complete digest before persistence. The interactive planner and internal background proposal publisher use this fence. Upgrade all Work writers before qualifying it; older writers that omit the shared lock are not covered. Calendar freshness and policy/approval checks remain independent.\n\nGoogle free/busy snapshots now carry normalized query provenance. Cache reuse requires the same calendars, time window and timezone, and rejects future or unbound observations. CompanyOS preparation requires covered planning time plus a matching refresh snapshot digest, evaluated at current server time after refresh. Additive migration 0085 adds query_binding; apply it before deploying the new store/read paths. Historical rows remain readable without earning freshness, and older refreshes cannot overwrite newer observations. Calendar identifiers stay in the tenant-scoped server store.\n\nInteractive Work proposals now retain opaque calendar snapshot/configuration evidence and reprove it in the publishing transaction before writes and again before return. Reproof locks current configuration and snapshot rows, rejects changed/disconnected/expired evidence, and restores the caller tenant setting. A workspace advisory lock also fences newly inserted preferences; both Google topology and event-preference writers participate. Upgrade these writers together before qualification. Provider calls remain outside this lock; no calendar effect is applied.\n\nPlanner topology selection distinguishes full scheduling preferences from event-calendar binding rows in the shared table. A newer binding without working hours cannot hide the workspace scheduling policy. A real PostgreSQL contention test verifies the actual event-preference writer waits for same-workspace publication while another workspace proceeds. Production rollout and broader load qualification remain separate.\n\n`createWorkSuggestionPolicyGuard` fills the existing proposal policy-guard port for explicit suggestion workers. It resolves current owner/policy before inputs and again after input and lease reproof, then uses the shared automation gate. The required reproveInputs callback must validate current calendar-then-Work revision evidence and return the actual input digest inside the same transaction. Other modes require their own verified command/approval/delegation composition; this helper does not enable a worker.\n\nPlanner input now includes all active focus occupancy owned by the personal user, with buffer margins. Other-workspace titles/timezones are reduced to Busy/UTC before leaving SQL; another user's rows are excluded. A semantic focus digest ignores provider sync metadata and is checked under the existing focus-intent lock before calendar and Work publication locks. No new migration or lock-key protocol is introduced.\n\n`generatePersonalWorkProposal` also returns its exact inputSnapshot for trusted internal workers; it is not added to HTTP responses. `createWorkSuggestionInputRevalidator` clones that input and proposal with owner, Work, focus and calendar evidence. It checks publication identity before SQL, then runs the concrete focus/calendar/Work checks in order, verifies current projected and completed Work revisions, and recomputes the private captured input digest. Use only trusted loader/optimizer output, not a client-supplied capture.\n\nPlanner reoptimization migration 0086 introduces one private owner/workspace queue entry for coalesced Work, calendar, focus, policy and recovery wakeups. Exact expiring claims fence atomic publication; resource guards precede queue row locks. Exhausted jobs require explicit current-authority reproof and a matching failed revision to repair. The adapter and local tests do not activate trigger fanout, a dispatcher, or production migrations.\n\nQueue-origin planner publication uses the existing WorkProposalPersistence with native job/ref revision identity and explicit queue guards. createQueueSuggestionInputRevalidator shares the trusted focus/calendar/Work input proof without requiring a fabricated Work event. These internal adapters do not activate a worker.\n\nPlanner cron /api/cron/planning-suggestions is scheduled every ten minutes for service principals and is a no-op until OPA_REOPTIMIZATION_ENABLED=1 (the global kill switch; OPA_PLANNING_SUGGESTIONS_ENABLED is no longer read). Activation requires migrations 0086, 0087 and 0130, the normal LSSM_STUDIO_DATABASE_URL, and a distinct MANAGED_COMPANYOS_PLANNING_DISPATCH_DATABASE_URL authenticated exactly as companyos_planning_dispatcher (function execution only; provision its password through the secret manager). Each run first drains due wakeups reserved with FOR UPDATE SKIP LOCKED (batch 20), then re-plans one cursor page of owners whose last run is older than two hours, within a 120 s budget and a 45 s per-owner timeout. Work mutations, task status changes and focus block changes enqueue savepoint-isolated, debounced (30 s) wakeups in their own transaction. Background planning is admitted when \"Plan work\" is \"Suggestions only\" or higher and paused by \"Manual only\"/\"Disabled\"; preconditions such as a stale calendar defer without consuming attempts, failures back off exponentially and dead-letter after five attempts until PlanningReoptimizationJobs.repair. A refreshed proposal is published only when it differs from the current plan and carries content-free diff provenance (opa.plan.refreshed); placements are never applied in the background.\n\nNotetaker bots (W5): `opa.bot_capture.*` routes under `/api/v2/opa/bot-captures/**` and `/api/v2/opa/bot-capture-settings` let a member send an Attendee notetaker bot to one Google Meet/Teams meeting after explicit recording consent and a confirmed participant notice (both recorded with the capture consent receipt in the append-only `opa_bot_capture_events` audit). Migration 0165 adds `opa_bot_captures` (encrypted meeting link, route digest, lease/attempt/dead-letter work queue), workspace settings and per-meeting switches. `/api/cron/opa-bot-dispatch` (start, observe, leave, import, provider cleanup, retention erasure) and `/api/cron/opa-bot-reconciliation` (webhook/observe wakeups over 0084) run every minute through `MANAGED_COMPANYOS_BOT_DISPATCH_DATABASE_URL` (exact `companyos_bot_dispatcher`). Callbacks arrive at `/api/webhooks/opa-bots/:routeToken` (route bound to one capture, signature verified). Global `OPA_BOTS_ENABLED=1`, workspace and meeting switches are rechecked before every provider call; switching off defers (global) or stops/leaves (workspace, meeting, lapsed consent). Recordings import into encrypted EU capture storage and finish into the EU transcription pipeline; without an EU speech model the EU-confirmed provider transcript (`OPA_BOTS_PROVIDER_TRANSCRIPT_REGION=eu`) or the recording alone is kept. Production stays off: see `docs/evidence/opa/opa-bots-production-readiness-2026-10-19.md`.\n\nWork planning enrollment: the planner and the background re-planner address an owner only through a Work identity binding (`managed_companyos_work_identity_bindings`, one per tenant, organization, workspace and user). `ensureWorkPlanningEnrollment` creates it after rechecking membership, organization authority and an enabled direct or team grant on an active, non-personal workspace, serialized per tenant, idempotent, with one `opa.work_planning.enabled` audit event. It runs on company workspace selection (best effort), on first plan generation, and from `POST /api/v2/opa/work-planning/enable` (`GET /api/v2/opa/work-planning` reports the state and never allocates). Existing users are enrolled with `bun run companyos:opa:backfill-work-planning` (`COMPANYOS_WORK_PLANNING_BACKFILL=dry-run`, then `=1`; output is per-organization counts only; re-runs report bindings as existing). Recovery counts an owner whose grants no longer allow background planning as paused rather than failed.\n\nPlanner inputs optionally carry unscheduledWork for owner-selected pending items requiring an estimate. They retain Work revisions, appear as estimate_required, and never receive invented durations or placements. Existing callers default to an empty list.\n\nTask split preferences use the existing scheduling proxy and opa.work_split_preference.get/save operations. Owner identity is server-derived; saves use revision CAS plus an idempotency receipt and enqueue replanning atomically. Apply migrations 0088/0089 and verify runtime grants before deploying this workflow. Absent/null preference remains unsplit, and saving never changes the Work estimate or applies calendar effects. Production acceptance remains pending.\n\n## Builder delivery authoring isolation\n\nEvery delivery route requires an authenticated tenant. The draft workspace uses a\nSHA-256 tenant namespace under `WORKSPACE_ROOT/.contractspec/builder-delivery-tenants/`.\nBody and query fields cannot select another tenant. Actor/operator references come\nfrom the authenticated principal; caller role descriptions confer no permissions.\nMissing-loop preflight returns 404. Shared legacy drafts are never read as a\nfallback: review ownership before explicitly adopting them into a tenant workspace.\nThis filesystem composition remains single-writer authoring storage, not the\nproduction multi-tenant state service.\n\nThe authenticated CompanyOS session-authority response includes `permissionRefs`\nfrom the canonical server role-permission resolver after fresh organization authority\nis established. Clients must not infer permissions from `grantRole` themselves.\nFleet read/manage keys are granted to the existing full-permission enterprise-admin\nrole; narrower roles and runtime deployment authority are unchanged.\n\nPublic Builder requests require an authenticated tenant. Supplied tenant IDs\nmust match that identity; missing tenant authority and mismatches fail before\nruntime execution. This boundary does not activate production deployment.\nAuthorized Builder request execution binds the authenticated tenant and principal\nto the existing RLS pool context. That context is scoped to the async request and\ndoes not persist into later requests.\n\nMember authoring uses fresh `contextAuthority.effectiveCapabilities`, not role\nnames or machine capability inheritance. The route contract is\n`src/handlers/builder/builder-member-policy.ts`: creation needs `builder.chat.web`\nand `builder.fusion.resolve`; intent/read needs `builder.chat.web`; blueprint,\nplan, preview and readiness need their exact fusion/compile/generate/harness grants.\nConfigure these through the existing organization/team/workspace authority store;\nno grants are installed automatically. Auditor and AI-operator mutations remain denied.\nMutations require the exact `APP_WEB_BASE_URL` origin and the current session CSRF\ntoken. All member reads/writes check tenant, owner and original organization/team/\nworkspace scope. Legacy unbound workspaces need explicit adoption before member use.\nCreation IDs are derived from the member, scope and request ID; the original request\nID can recover a lost response in the same context. Creation replay reads existing\nstate instead of regenerating it. Member payloads cannot choose owners, providers,\nchannels or authority. Execution/release endpoints remain outside this admission.\n\nVercel source uploads exclude TypeScript and JavaScript test entrypoints through\nroot `.vercelignore`. In particular, `api/index.test.js` remains part of local QA\nand must not appear as a deployed serverless function alongside `api/index.js`.\n\n## Preview authentication\n\n`COMPANYOS_AUTH_PROFILE=preview-v1` selects the additive preview topology. Set\n`COMPANYOS_PREVIEW_WEB_ORIGIN` and `COMPANYOS_PREVIEW_API_ORIGIN` to exact HTTPS\norigins outside the production cookie domains. In the API, `BETTER_AUTH_BASE_URL`\nand `APP_WEB_BASE_URL` both equal the preview **web** origin because browser auth\nuses its same-origin proxy. Configure `AUTH_PROVIDER_MODE=better-auth`, a dedicated\n`COMPANYOS_PREVIEW_AUTH_SECRET` (at least 32 characters), and\n`COMPANYOS_PREVIEW_DATABASE_URL`. `LSSM_STUDIO_DATABASE_URL` must match that database;\noptional auth/channel database references must also match. Unset `BETTER_AUTH_SECRET`,\n`BETTER_AUTH_COOKIE_DOMAIN` and production federation flags. Production Vercel\ndeployments cannot select this profile. Cookies use the `companyos-preview` prefix,\nno parent domain, and the preview web origin for passkeys.\n\nProvision and verify dedicated data and credentials before enabling this profile.\nMatching configuration strings are not evidence of actual provider isolation.\nDatabase migrations, synthetic accounts, callback behavior, session revocation,\ntenant checks and deployed browser sign-in still require qualification.\n\nBetter Auth account identity requires `issuer` plus `account_id`. Apply tracked\nmigration `0090` before deploying the updated Drizzle account schema. It preserves\npassword hashes and normalizes password-bearing `credential` rows to\n`local:credential` plus `user_id`; ambiguous duplicates abort atomically. It does\nnot guess OAuth issuers. Existing external accounts with a null issuer require\nprovider-specific reconciliation and login qualification before production\npromotion. Newly created accounts receive the issuer from Better Auth itself.\n\n## Standalone container hosting\n\nAfter `build:elysia`, `start:elysia` runs `server.mjs`, binds HTTP on `PORT`\n(default 3000), and handles SIGTERM/SIGINT through the app lifecycle with a bounded\nshutdown deadline. The Vercel adapter still imports the same application bundle.\nBuild the package Dockerfile from the repository root. Its pinned Node/Bun build\nstages produce a non-root Bun runtime containing only the built API, packaged Loro\nruntime and standalone entrypoint. Use the root route as a process-start probe;\ndatabase, identity and application-journey readiness require separate checks.\nIn preview mode, login discovery omits email-delivery methods when Resend is not\nconfigured; password login remains available for provisioned synthetic accounts.\n\nThe standalone Bun launcher emits fixed startup phases: loading, loaded and\nlistening. Import failure and a 90-second import deadline fail startup without\nlogging credentials or exception payloads. These markers diagnose startup;\nonly the listening application answers health checks.\n\n## Builder company context\n\n`builder.companyContext.resolve` and POST `/api/companyos/builder/context/resolve`\naccept an owned Builder workspace and a question up to 4096 UTF-8 bytes. The shared\nmember surface invokes this query through the authenticated web BFF. Missing\nconfiguration returns 503; query failures are never retried as saved mutations.\n\nThe host binds the persisted Builder workspace to its verified actor and selected\ncompany context. Current Company Intelligence Brain authorization and field\nprojection select approved, fresh, visible entries. Contradictory sources refuse\nretrieval. Canonical source/version/asset/part/fragment/evidence records are checked\nfor tenant, ACL, validity, deletion and supersession, then re-read after storage IO.\nPoint reads filter object identity before pagination. Verified citations retain\nsource, redaction and replay references even when the question paraphrases them.\nKnowledge supplies context; existing release and execution permissions still apply.\n\n### Shared server startup\n\nBoth standalone Bun and serverless requests use `getBuilderRuntimeResources`.\nIts first initialization reads the optional server-only\n`BUILDER_GROUNDING_CONFIGURATION` JSON through the versioned\n`BuilderGroundingStartupManifestSchema`. Unconfigured, malformed, expired or\nmissing-secret profiles leave authoring available and grounding unavailable.\n`getBuilderGroundingStartupState` reports a static configuration state without\nsecret details. A configured state is not a live qualification result.\n\nThe manifest names explicit models, independent contexts, allowed tenant/workspace\npairs, a request limit per minute, review/retrieval/code references and approved\nsource objects/excerpts. It uses the existing AI provider factory and\n`SecretProviderManager` with environment-backed references:\n\n- `env://BUILDER_GROUNDING_MODEL_SECRET` may serve both model roles.\n- `env://BUILDER_GROUNDING_DRAFTER_SECRET` and\n  `env://BUILDER_GROUNDING_VERIFIER_SECRET` allow separate accounts.\n- `env://BUILDER_GROUNDING_STORAGE_SECRET` contains the existing S3 connection\n  fields: accessKeyId, secretAccessKey, HTTPS endpoint, region, bucketName and\n  urlStyle. Keep credentials in deployment secrets, outside the manifest.\n\nOpenAI, Anthropic, Mistral and Gemini use explicit model IDs through the canonical\nfactory. The same vendor/account can serve both roles when model identity and\nindependence domain differ. Separate role clients receive independent prompts and\ncontexts. Models get no tools, automatic retries are disabled, and canonical\nclaim/citation verification remains mandatory.\n\nEach source approval binds an opaque storage reference to an exact S3 bucket/key,\nbyte cap, SHA-256 and optional object version. Each reviewed excerpt additionally\nbinds its evidence ID, content SHA-256 and redaction decision. Only matching\ncanonical text/plain line excerpts enter a model. Asset reads are bounded to\n1 MiB and excerpts to 16 KiB. PDF/media extraction requires another qualified\nprofile. Storage cancellation bounds waits and requests stream teardown; it does\nnot independently establish that remote IO stopped.\n\nThe profile scope intersects existing Brain authority. It does not grant an\noperations manager administrative content access. Eligible model requests consume\nthe existing tenant/principal Company Intelligence request quota first; unavailable\nquota persistence fails closed. The runtime needs source/Brain SELECT permission\nand the existing `managed_companyos_ci_api_budgets` SELECT/INSERT/UPDATE path under\nFORCE RLS. Source provisioning remains an operator-owned canonical repository\noperation. Request quotas do not replace monetary reservation/reconciliation.\n\nConfiguration and clients are reused across warm requests. Deploy/restart after\nchanging a manifest or environment-backed secret. Trusted tests or explicit host\ncompositions can still use `configureBuilderRuntimeGrounding` before the first\ninitialization; rebinding an active singleton is refused.\n\n### Qualification status\n\nActual Railway S3 and constrained PostgreSQL qualification verified six canonical\nrecords and the exact 176-byte synthetic source, including replay with zero new\neffects and cross-tenant denial. The complete SQL-to-answer composition is tested\nwith mock model/storage ports. Live model connections, cancellation, redaction,\nspend reservation and full member journeys require separate qualification before\nproduction acceptance. No member Brain grant or model call is implied by the\nsource-read proof.\n\n\n### Critical production schema build gate\n\nThe Vercel production build first runs `scripts/critical-schema-preflight.ts`.\nIt requires `account.issuer` (text) on the resolved authentication database and\n`opa_google_availability_snapshots.query_binding` and\n`managed_companyos_personal_briefing_deliveries.generation_provenance` (jsonb)\non the runtime database.\nThe probe uses a read-only PostgreSQL session, metadata inspection and zero-row\nSELECTs, with five-second connection, ten-second statement and five-second close\nbounds. Missing configuration, incompatible columns or unavailable read access\nfail the build; previews explicitly skip without qualification. Credentials and\nSQL error details are never printed. The gate never migrates or reads customer\nrows. Use the existing authorized migration workflow to repair prerequisites.\n\nThis proves only these columns and read access, not account reconciliation, all\nmigrations, booking journeys or full readiness. The snapshot column is derived\nfrom current source requirements, not a confirmed diagnosis of the particular\ncolumn behind the observed production SQLSTATE 42703. This app-owned deployment\ncontract is not an operation spec; no CLI operation-validation success is claimed.\n\n\nPlanner rollout preflight v1.1 rejects missing or duplicate required catalog entries and checks physical topology_version, workspace_id and query_binding columns, including migration 0091 prerequisites. Failures remain content-free. It is read-only: it does not apply migrations, repair schema, or prove provider execution and full workflow readiness.\n\n### Calendar briefing model provenance\n\nApply migration 0092 before deploying the briefing store: finish writes nullable generation_provenance JSONB even for deterministic drafts. Legacy receipts remain unqualified with null provenance. CompanyOS keeps direct Mistral disabled. Gateway generation additionally requires the private-processing admission adapter described in \"AI-written, cited briefings (OPA)\" above; without it the labelled template is sent. Accepted generation requires supplied citation validation, explicit served EU/provider evidence, stop completion, text-only output and post-generation admission recheck. Prompt size is bounded to 80000 serialized characters. Neither environment configuration nor a briefing delivery toggle grants private-processing authority. No live activation is established by this slice.\n\n### AI-written, cited briefings (OPA)\n\nMorning recaps, meeting preparation, preview e-mails and private drafts share\none generator (`src/calendar/opa-ai-briefing-*`). A briefing is written through\nthe Vercel AI Gateway only when the private-processing admission adapter admits\nthe owner. Otherwise the deterministic template is sent and labelled\n(\"Standard template — <reason>\"). Admission requires, in order:\n\n1. `OPA_AI_BRIEFINGS_ENABLED=1`;\n2. the approval references `OPA_AI_BRIEFINGS_PROCESSING_APPROVAL_REF` and\n   `OPA_AI_BRIEFINGS_GATEWAY_TRANSIT_APPROVAL_REF`, and a Gateway credential\n   resolved per request by `@lssm-tech/lib.ai-providers/vercel-gateway-auth`:\n   `AI_GATEWAY_API_KEY`, else on Vercel the invocation's `x-vercel-oidc-token`\n   header (pinned to `VERCEL_PROJECT_ID` when exposed), else\n   `VERCEL_OIDC_TOKEN`. Cron, preview, settings and draft routes pass their\n   request, so scheduled runs on Vercel Functions authenticate too;\n3. the owner's explicit opt-in (Settings → Personal briefings → AI briefings).\n   It is stored in the owner-only consent record and bound to a digest of the\n   processing policy (catalog, EU routing, zero retention, no training, sent\n   fields, approvals). A policy change makes the consent stale and asks the\n   owner again;\n4. an organization automation policy that does not disable\n   `intelligence.generate`, plus the `opa.meeting_outcome.analyze` capability;\n5. a model from the shared catalog\n   `@lssm-tech/lib.provider-spec/gateway-model-catalog`.\n\nModel precedence: owner override → workspace default → `OPA_AI_DEFAULT_MODEL`\n→ catalog default. Organization owners and admins with the enterprise-admin\ngrant set the workspace default (migration `0125`,\n`opa_ai_briefing_workspace_models`). Before `0125` is applied the workspace\ndefault reads as empty and cannot be changed; everything else works.\n\nOnly event titles, times, attendee display names and agendas are sent. E-mail\nfallbacks for attendees are reduced to their local part, and links, e-mail\naddresses and phone numbers are removed from agendas. Company knowledge is\nadded only when the owner selects it. Every claim must cite a supplied source:\nunknown citations are removed, uncited claims are dropped, and output without a\ncited summary falls back to the template. Admission is re-proved before and\nafter each call, and the served route must prove EU inference.\n\nAI briefings record provenance 1.1.0 in `generation_provenance`: model, prompt\nversion, sources digest, generation time, model source and citation count.\nSettings changes append\n`companyos.calendar_intelligence.ai_briefings.settings_changed` to\n`managed_companyos_audit_events`. Endpoints: `GET|POST\n/api/companyos/opa/briefings/ai-settings` (owner) and `GET|POST\n/api/companyos/opa/briefings/ai-settings/workspace` (administrators).\n`GET /api/companyos/health/degraded` reports the secret-free\n`opaAiBriefings` status (`enabled`, `disabled_flag`, `missing_approval`,\n`no_gateway_auth`); it never degrades overall health.\n\n### Meeting context sources (OPA preparation and AI briefings)\n\n`src/organization-planning/meeting-context/` binds one aggregate knowledge\nsource, `knowledge:companyos-meeting-context`, into meeting preparation (next\nto the Work Graph source) and into AI briefings. On every load it re-reads the\nowner's source choices (stored with the AI processing consent; revoked consent\nenables nothing) and runs each enabled adapter inside a\n`MeetingContextSourceBudget` (items, bytes, time, 15-minute TTL snapshot cache\nso generation reproofs see the same context). A failing or slow adapter adds\nnothing and logs `opa_meeting_context.source_collected` with a stable code; no\nprovider id, e-mail address or message body is logged.\n\n| Owner kind | Adapter | Store / grant |\n| --- | --- | --- |\n| `tasks` | open Work tasks, personal workspace | Work event log, `workspace.read` |\n| `communication-history` | meeting threads + recent messages | CommunicationOS journal, owner personal scope |\n| `participants` | attendees × HubSpot contacts | live calendar read + `opa_oauth_tokens` `hubspot` |\n| `drive`, `notion`, `slack` | title search, metadata only | `opa_oauth_tokens` `google-drive`, `notion`, `slack` |\n| (always, consent-gated) | PersonalOS context | unbound until PersonalOS ships a consented read |\n\n`OPA_MEETING_CONTEXT_SOURCES` (comma list: `communication-history`,\n`participants`, `drive`, `notion`, `slack`, `hubspot`) decides which kinds the\ndeployment offers; unset offers none, so deploying changes nothing. Grants use\n`accountRef = individual:<authority segment of the user id>` in the physical\ntenant. Token refresh uses `GOOGLE_DRIVE_OAUTH_CLIENT_ID/SECRET` (Drive's own\nGoogle client; refused when it equals the calendar client, because Google\nrevocation drops every scope a user granted one client) and\n`HUBSPOT_OAUTH_CLIENT_ID/SECRET`.\n\n#### Meeting context connections (OAuth connect flows)\n\n`meeting-context/oauth-connect-routes.ts` implements\n`OPA_MEETING_CONTEXT_CONNECTIONS_CONTRACT` (organization-planning spec) for\nthe owner's personal grants. The routes are composed into the\npersonal-briefings plugin, so the web BFF reaches them under\n`/api/companyos/opa-os/briefings/meeting-context/*`:\n\n| Route | Gate | Answer |\n| --- | --- | --- |\n| `GET …/meeting-context/connections` | session + personal context | per provider: `connectable` (listed in `OPA_MEETING_CONTEXT_CONNECT_SOURCES` and an OAuth client set), `offered` (listed in `OPA_MEETING_CONTEXT_SOURCES`), `state` |\n| `POST …/meeting-context/{provider}/connect` | trusted web origin | `{ authorizationUrl }` (https consent page) |\n| `GET …/meeting-context/{provider}/callback` | the same session | always 303 to `/companyos/opa-os/settings?meetingContext=connected\\|failed&provider=…[&reason=…]`; an ended session is `reason=session_required` |\n| `POST …/meeting-context/{provider}/disconnect` | trusted web origin | `{ provider, state: 'not_connected' }` |\n\nProviders and consent scopes: `google-drive` (`drive.metadata.readonly`, PKCE,\noffline access; client `GOOGLE_DRIVE_OAUTH_CLIENT_ID/SECRET`, never the calendar one),\n`notion` (owner=user; `NOTION_OAUTH_CLIENT_ID/SECRET`), `slack` (user scope\n`search:read`, token rotation off; `SLACK_OAUTH_CLIENT_ID/SECRET`) and\n`hubspot` (`oauth crm.objects.contacts.read`; `HUBSPOT_OAUTH_CLIENT_ID/SECRET`).\nThe provider redirect URI is the API callback,\n`${BETTER_AUTH_BASE_URL}/api/companyos/opa/briefings/meeting-context/<provider>/callback`\n(default origin `https://api.companyos.run`), and must be registered with each\nprovider app. A provider shows \"Connect\" only once the operator lists it in\n`OPA_MEETING_CONTEXT_CONNECT_SOURCES` (`drive`, `notion`, `slack`, `hubspot`)\nafter registering that redirect URI and scopes, so a client already set for\nrefresh never sends owners to an unprepared consent page.\n\nThe OAuth state is sealed with the BYOK cipher under the owner's personal\ntenant key and names the provider, user, a session digest, the PKCE verifier\nand a ten-minute expiry. The single live attempt per owner and provider is\nrecorded in `opa_oauth_tokens` (provider `meeting-context-oauth-state:<provider>`)\nand consumed under a row lock before the code exchange, so a replayed,\nparallel or superseded callback fails without a provider call. The row holds\nonly the nonce digest; one inert row per owner and provider remains until the\npersonal context is deleted. A grant missing the source's required scope, or\none the vault fails to store, is revoked and not stored. Grants are stored\nunder the reader key above. Disconnect\nasks the provider to revoke (Google, Slack, HubSpot; Notion has no revocation\nendpoint, so the owner removes the integration in Notion), then overwrites the\nrow with an inert token: `opa_app` has no DELETE policy on `opa_oauth_tokens`,\nso the delete only succeeds for a role that may delete.\n\nConnecting never enables a source. List a kind in `OPA_MEETING_CONTEXT_SOURCES`\nonly after its connect flow passed an end-to-end canary on the deployment.\n\nThe PGlite suites (`*.pglite.test.ts` in `meeting-context/`) run against a\ndisposable local PostgreSQL instead when `OPA_MEETING_CONTEXT_TEST_DATABASE_URL`\nnames a local server (each file creates and drops its own database).\n\nVercel delegates API production builds to `scripts/vercel-build.ts`, keeping the configured command below the platform limit. The orchestrator runs the critical-schema gate before crypto utilities, LSSM OS contracts and API compilation, and stops on the first failure.\n\nRuntime schema diagnostics distinguish absent columns from incompatible types, inspect role attributes and the planning migration ledger, and optionally compare the expected Supabase project/database. Only status and coarse classifications are returned; the script does not print connection details, read customer rows, migrate or grant authority.\n\n## Builder candidate routes\n\n`POST /api/companyos/builder/plans/{prepare,approve,execute,status}` uses the\nexisting member/session/CSRF admission and Builder capabilities. Prepare/status\nrequire `builder.plan.compile`; approve/execute require `builder.plan.execute`.\nThe server resolves identity and workspace scope, strips caller authority, and\nforwards only reviewed plan reference and request identity to the runtime.\nReturned available actions are intersected with current actor capabilities.\nConfigure the concrete `BuilderCandidateService` through trusted runtime\ncomposition; no default approval, order issuance or successful execution exists.\n\nPrivate briefing consent and non-delivering draft previews require migrations 0093/0094. Explicit consent binds model and source scope; signed one-use human-command receipts bind current policy and inputs. Failed generation does not silently rerun under the same command. Concurrent revocation can wait behind active shared locks, and new-table retention/deletion integration remains incomplete; these routes are not production-qualified. Microsoft identity and isolated OAuth storage require 0095/0096, with legacy Microsoft state/credential reconciliation before cutover.\n\nLocal/test reset now removes private draft command receipts, processing consents and Microsoft identity/OAuth state before personal context rows. This prevents stale authority surviving a test reset; it does not implement production erasure or retention, which remain separate outstanding workflows.\n\nThe new Microsoft-only vault uses encryption domain v2, binding tenant, workspace, user, provider purpose and account reference. Ciphertext copied between accounts or OAuth/PKCE purposes fails authentication. It does not accept the earlier unactivated owner-only domain; any pilot rows written with that draft implementation require controlled reauthorization rather than silent decryption fallback. This does not change the shared Google vault.\n\nMicrosoft vault envelope v3 supersedes the local v2 draft and additionally authenticates scopes/expiry. Reads reject metadata mismatches; no old envelope is silently accepted. No production vault migration or Microsoft activation is claimed.\n\nPrivate briefing handlers use the existing streaming bounded JSON reader: draft input is capped at 4096 bytes and processing consent at 64000 bytes. Oversized bodies return 413 after authentication/origin checks and before service execution; malformed/non-object JSON returns 422.\n\n## Local Builder installation\n\nFrom this package, enroll a private local owner once:\n\n```sh\nbun scripts/install-local-builder-owner.ts /absolute/local/auth http://127.0.0.1:43119 local-tenant local-workspace 'Local Builder'\nbun scripts/serve-local-builder.ts /absolute/local/auth /absolute/local/authoring\n```\n\nEnrollment writes a private owner profile and prints only its path. Do not expose\nor commit that file. The launch command binds the configured loopback origin and\nexposes no public signup or organization administration. Pair through\n`POST /local/auth/pair` with the configured Origin and the local pairing credential\nas Bearer authentication; the result sets an HttpOnly session cookie. Subsequent\nBuilder mutations require that cookie, the exact Origin and `x-csrf-token` equal\nto the session ID returned by `GET /local/auth/session`.\n\nThe shipped launch command enables durable authoring only. It does not configure\ncandidate execution. Programmatic `createLocalBuilderApplication` may receive a\nqualified candidate service composed by `createBuilderCandidateLocalHost`; all\nproject, topology, worker, policy, signing and recovery evidence must be supplied\nexplicitly. Grant removal is reread for every session check; new grants cannot\nbroaden an already-running local authority. Sign-out revokes the current session.\n\nClose drains in-flight work before database shutdown. An unconfirmed drain retains\nstorage ownership for reconciliation. This local API increment does not claim a\ncomplete console UI, live generated candidate, hosted preview or release workflow.\n\n`verifyEncryptedBackup` authenticates the complete encrypted backup stream, validates manifest sizes/hash and computes a plaintext digest without returning or writing plaintext. It retains restoreVerified:false: cryptographic integrity is not a PostgreSQL restore rehearsal, independent key custody or PITR qualification.\n\nSubmit an outcome to the running local authoring API without manually copying\ncookies or session IDs:\n\n```sh\nbun scripts/local-builder-intent.ts /absolute/local/auth 'Create an accessible project checklist'\n```\n\nThe command reads the private local profile, pairs through AuthOS, submits the\nintent with session/CSRF binding, and signs out its temporary session. Output\ncontains only the workspace identity and acceptance status. It does not execute\na candidate, call a model, or ship a release.\n\n### Personal Microsoft calendar OAuth\n\nPersonal connection contracts expose POST `/api/v2/opa/personal-calendar/microsoft/authorize` and GET `/api/v2/opa/personal-calendar/microsoft/callback`. Ownership comes from the authenticated personal context. PKCE state and encrypted credentials use the Microsoft-only owner-scoped storage; callbacks pin verified Microsoft identity. These operations do not yet provide calendar discovery or qualify booking/planning integration. Production activation requires configured Microsoft credentials/callback, migrations and least-privilege grants, followed by real account acceptance.\n\nGET `/api/v2/opa/personal-calendar/microsoft/calendars` enumerates the current personal connection through the verified account runtime. Its response is bounded and excludes raw provider identifiers and credentials. Calendar selection and planner activation remain separate steps.\n\n**Graph scopes (least privilege).** The app requests exactly `offline_access` (refresh), `User.Read` (`GET /me` id pinned before credentials persist) and `Calendars.Read` (calendar list and `calendarView` reads). CompanyOS writes nothing to Microsoft calendars (focus blocks and bookings go to Google only), so `Calendars.ReadWrite` is no longer requested; grants consented earlier with it stay valid. The Entra app registration only needs these delegated permissions; a future Microsoft write effect needs a reviewed scope change and owner re-consent.\n\n**Reauthorization.** A refresh refused by the Microsoft identity platform (`invalid_grant` — expired/revoked refresh token, revoked consent —, `interaction_required`/`consent_required`/`login_required`, or any other 400/401 except `invalid_client`/`unauthorized_client`) moves the personal `opa_calendar_connections` row from `connected` to `reauthorization_required` and enqueues one `opa.calendar.reauthorization_required` outbox alert (`providerKind: microsoft`), in a fresh transaction after the failed read rolled back. The maintenance cron relays it as one en/fr/es email to the owner, linking `/companyos/opa-os/settings`. Discovery, selection save and briefing reads then answer `409 CALENDAR_REAUTHORIZATION_REQUIRED` without calling Microsoft until the owner reconnects; a successful OAuth callback restores `connected`. 429/5xx/`temporarily_unavailable`/timeouts are transient (`503 MICROSOFT_CALENDAR_UNAVAILABLE`, `Retry-After` when Microsoft sent one) and never change state; `invalid_client` is logged as `microsoft_calendar_connection.client_rejected` (operator fault). GET `/api/v2/opa/personal-calendar/microsoft/health` returns `{ reauthorizationRequired, checkedAt }` from stored state only; the web shell uses it for the reconnect banner on every OPA page. Recorded-shape fixtures for these responses live in `packages/integrations/provider-calendar/test/fixtures/microsoft/`.\n\n### Published profile handle reservations\n\nApply migration `0097` before deploying profile draft-renaming changes. It permits separate live and draft reservations while retaining global handle uniqueness. Backfill aborts on conflicting historical claims; operators must reconcile those claims without stealing another profile’s handle. Publication releases the previous reservation in the same transaction as its public-pointer update.\n\n### Native scheduling authorization\n\nPersonal scheduling mutations accept verified native bearer sessions without an Origin header. Invalid bearer credentials never borrow a browser cookie session. Cookie-authenticated browser requests retain exact-origin validation. Domain session, membership and policy checks remain required; transport authentication alone grants no scheduling effect.\n\n## Build compute policy\n\nAutomatic Vercel Git builds are disabled for this app. Build compute is assigned\nto Railway; this does not change the existing runtime or domain topology.\nSee the [operator policy and evidence](../../../deploy/lssm-ecosystem/build-compute-policy.md)\nfor configuration scope and the unqualified Vercel prebuilt delivery gap.\n","sourcePath":"packages/apps/api-application-monolith/README.md","sourceUrl":"https://github.com/lssm-tech/contractspec/blob/bcc79fcc27c4d801c2119bef81ddcce7b4e86498/packages/apps/api-application-monolith/README.md","blobSha":"cd4ffe2f02f51708515028a093780144806b7e34","sourcePin":"bcc79fcc27c4d801c2119bef81ddcce7b4e86498","origin":"README recovered byte-for-byte from pinned aggregate guide","integrity":"exact Git blob match","executionStatus":"not executed"},"provenance":{"repository":"lssm-tech/contractspec","sourcePin":"bcc79fcc27c4d801c2119bef81ddcce7b4e86498","manifestOrigin":"pinned GitHub manifest fetch","manifestComplete":true,"publicationPolicyApplied":false},"areaSlug":"app-composition","areaTitle":"Application composition and product hosts","displayName":"app.api-application-monolith","runtimes":[],"platforms":[],"kind":"apps","scope":"Workspace only","canonicalRoute":"/docs/packages/app.api-application-monolith/","contextUrl":"/docs/packages/app.api-application-monolith.context.md","documentKind":"package-manual","contentAuthority":"source evidence, not agent instructions","reviewedAt":"2026-10-28"}