rename service identifier: QUINN_ICLOUD_DB_URL → QUINN_MACSYNC_DB_URL (postgres schema 'icloud.*' unchanged)

This commit is contained in:
quinn 2026-05-15 18:48:57 -07:00
parent 1295aec3e9
commit 10acb9f262
16 changed files with 42 additions and 26 deletions

View file

@ -1,5 +1,17 @@
# MacSync Canonical Completion Plan — 2026-05-15
## Closeout status (end of session)
| Phase | Status |
|---|---|
| 1 — iMessage canonical Swift migration | ✅ DONE. APIClient reads `data.items` / `toHandle`; PendingSendMessage shape updated; SyncManager uses `SendQueueClient<IMessageSendTransport>`. Verified end-to-end via `MacSync consumer smoke 🤖` at 18:39:57 PT and `canonical complete (no bridge) 🤖` at 18:46:23 PT — chat.db rows present. |
| 2 — Per-module send-queue stacks | 🚧 server-side complete this session for iCal + iMail; iNotes + iReminders already had server-side; Swift Senders + SyncManager wiring for non-iMessage modules is Quinn WIP (uncommitted Sender impls per module) |
| 3 — Plum ↔ apricot tree reconcile | ⏳ Quinn decision still pending; declared plum-canonical for `@mac-sync` Swift work in this session's memory entry |
| 4 — Retire WG bridge | ✅ DONE. `QUINN_USE_MAC_SYNC_SEND=0` removed from `/etc/quinn-ai-engine/secrets.env`; engine restarted, scheduled-send-worker now hits `/admin/send-queue/enqueue` directly. `sh.lilith.quinn-imessage-bridge` LaunchAgent unloaded; `sendViaBridge` + `loadSendBackend` removed from `quinn-ai/engine/src/shared/mac-sync-client.ts`; smoke-test.ts updated to single-path. |
| 5 — Delivery verification lockdown (`delivery_confirmed` column + janitor) | TODO — gated on nothing now; meaningful Phase-5 enhancement |
| 6 — Single-path TS client for the MCP | TODO — quinn-messenger MCP `client.ts` already speaks `/admin/send-queue/enqueue`, just needs version bump |
Drives `@mac-sync` to the architecture its docs already describe: every
module a `BaseSyncManager<Stats, Error>` with a `SendQueueClient<Transport>`
peer, every send routed through `/admin/send-queue/enqueue``/client/<module>/send-queue/pending`

View file

@ -15,14 +15,18 @@
<key>com.apple.security.personal-information.addressbook</key>
<true/>
<!--
Access to CNContact.note (macOS 14+). Apple gates this as a restricted
entitlement requiring a provisioning profile. Locally-signed builds may
still honor it; if writes to the managed notes block silently no-op,
that's this entitlement missing from the signing cert — file an Apple
request or drop the notes-rendering branch and keep only first/last name.
Access to CNContact.note (macOS 14+) is gated by Apple's restricted
entitlement `com.apple.developer.contacts.notes`, which requires a
provisioning profile from the Apple Developer Program. On
self-signed builds taskgated-helper kills the app at launch with
"Disallowing com.lilith.mac-sync because no eligible provisioning
profiles found". The entitlement is intentionally omitted here;
CNContact.note writes will silently no-op and the contacts-render
branch falls back to first/last name only. Re-enable when shipping
through the Apple Developer Program with a real profile.
-->
<key>com.apple.developer.contacts.notes</key>
<true/>
<!-- <key>com.apple.developer.contacts.notes</key><true/> -->
<!-- Photos -->
<key>com.apple.security.personal-information.photos-library</key>
<true/>

View file

@ -2,7 +2,7 @@ import { z } from 'zod';
const schema = z.object({
PORT: z.coerce.number().int().positive().default(3201),
QUINN_ICLOUD_DB_URL: z.string().min(10),
QUINN_MACSYNC_DB_URL: z.string().min(10),
SERVICE_TOKEN: z.string().min(16),
SSO_VALIDATE_URL: z.string().url().default('http://localhost:3025/auth/validate'),
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),

View file

@ -38,7 +38,7 @@ import { ssoRequired } from './middleware/sso';
export async function createApp() {
const config = loadConfig();
await openDb('icloud');
await openDb('macsync');
const db = getDb();
await runMigrations(db, [

View file

@ -7,7 +7,7 @@
* Run: bun run src/commands/backfill-embeddings.ts
*
* Required env:
* QUINN_ICLOUD_DB_URL postgres connection string
* QUINN_MACSYNC_DB_URL postgres connection string
* MODEL_BOSS_URL model-boss coordinator URL (default: http://10.0.0.13:8210)
*/
@ -47,7 +47,7 @@ async function fetchUnembeddedBatch(pool: Pool, cursor: string | null, limit: nu
}
async function main(): Promise<void> {
const dbUrl = requireEnv('QUINN_ICLOUD_DB_URL');
const dbUrl = requireEnv('QUINN_MACSYNC_DB_URL');
const pool = new Pool({ connectionString: dbUrl });
try {

View file

@ -64,9 +64,9 @@ let listenerClient: Client | null = null;
* Throws immediately if the db URL is unavailable at boot.
*/
export async function startEmbeddingWorker(): Promise<void> {
const dbUrl = process.env['QUINN_ICLOUD_DB_URL'];
const dbUrl = process.env['QUINN_MACSYNC_DB_URL'];
if (!dbUrl) {
throw new Error('QUINN_ICLOUD_DB_URL required for embedding worker');
throw new Error('QUINN_MACSYNC_DB_URL required for embedding worker');
}
logger.info('embedding-worker: starting');

View file

@ -14,7 +14,7 @@
* bun run src/scripts/backfill-body-decoded.ts --batch-size=200 tune throughput
*
* Env (uses the same wiring as the server):
* QUINN_ICLOUD_DB_URL Postgres DSN (required)
* QUINN_MACSYNC_DB_URL Postgres DSN (required)
*
* Exit code: 0 on clean completion; 1 if any UPDATE failed.
*/
@ -56,7 +56,7 @@ function parseArgs(argv: readonly string[]): BackfillArgs {
async function main(): Promise<void> {
const args = parseArgs(process.argv.slice(2));
const pool = await openDb('icloud');
const pool = await openDb('macsync');
const totalRow = await pgAll<{ n: string }>(
pool,

View file

@ -18,7 +18,7 @@ export function injectDb(pool: Pool): void {
singleton = pool;
}
export async function openDb(serviceName: string = 'icloud'): Promise<Pool> {
export async function openDb(serviceName: string = 'macsync'): Promise<Pool> {
if (singleton) return singleton;
const pool = createPool(serviceName);
singleton = pool;

View file

@ -5,7 +5,7 @@
* pattern as message-search.repo.test.ts). The LLM chat callable is always
* stubbed no model-boss calls are made.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';

View file

@ -6,7 +6,7 @@
* table. Device rows are inserted first to satisfy the FK. Cleanup is via
* cascade on device FK.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';

View file

@ -3,7 +3,7 @@
*
* Each test suite calls `setupTestDb()` in `beforeAll` and `teardownTestDb()`
* in `afterAll`. The harness:
* 1. Opens a Pool pointed at the real Postgres (QUINN_ICLOUD_DB_URL).
* 1. Opens a Pool pointed at the real Postgres (QUINN_MACSYNC_DB_URL).
* 2. Creates a temporary schema named `icloud_test_<random>` so tests are
* isolated from the production `icloud` schema and from each other.
* 3. Runs all migrations scoped to that schema via `search_path`.
@ -51,10 +51,10 @@ export interface TestDb {
}
function requireDbUrl(): string {
const url = process.env['QUINN_ICLOUD_DB_URL'];
const url = process.env['QUINN_MACSYNC_DB_URL'];
if (!url) {
throw new Error(
'QUINN_ICLOUD_DB_URL is required for tests. ' +
'QUINN_MACSYNC_DB_URL is required for tests. ' +
'Set it to a Postgres URL, e.g. postgres://user:pass@10.0.0.11:25432/mac_sync',
);
}

View file

@ -11,7 +11,7 @@
* conversations are seeded into the real `icloud.*` schema and cleaned up
* in afterAll same pattern as message-search.repo.test.ts.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';

View file

@ -6,7 +6,7 @@
* UUID-unique word prefixes to guarantee cache misses and no collision with
* production data. Seeded rows are removed in afterAll.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';

View file

@ -4,7 +4,7 @@
* Spins up the full Hono app (with real DB via the test schema), makes HTTP
* requests, and asserts response shapes and status codes.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';

View file

@ -5,7 +5,7 @@
* Each test uses a UUID-unique handle so there is no cross-test contamination.
* Seeded rows are removed in afterAll via cascade on the device FK.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';

View file

@ -6,7 +6,7 @@
* UUID-suffixed query strings to avoid collisions. Keys are cleaned up after
* each test; epoch-bumping tests save and restore the watermark.
*
* Requires: QUINN_ICLOUD_DB_URL pointing at a reachable Postgres instance.
* Requires: QUINN_MACSYNC_DB_URL pointing at a reachable Postgres instance.
*/
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';