/** * Resolve the DESKTOP installation identity that is actually enrolled in the * client-health registry (US-004). * * WHY THIS EXISTS * --------------- * `POST /v1/sync-manifest/upload` is fenced on enrolment: hq-pro's * `processSyncManifestUploadRequest` calls `isInstallationEnrolled(personUid, * upload.installationId)`, which is * `clientHealthStore.getSnapshot(personUid, installationId) !== null`. An * installation id that no client-health heartbeat has ever reported gets a * hard **403 INSTALLATION_NOT_ENROLLED** — the manifest row can never join the * heartbeat row, so the whole audit is silently dead for that host. * * WHO ENROLS A DESKTOP HOST * ------------------------- * Not hq-cloud: the sync engine sends no client-health heartbeat at all. The * HQ Sync menubar app does, from Rust * (`hq-desktop-app/apps/sync/src-tauri/src/commands/client_health.rs`). It * pins its identity in `~/.hq/client-health.json` (`state_file_path()`), whose * `ClientHealthState` is `#[serde(rename_all = "camelCase")]` — so the JSON * key is `installationId`. The value is seeded on first use from * `~/.hq/menubar.json`'s `machineId` when that is wire-shaped, else a fresh * v4 UUID. * * That is NOT the same thing as `getOrCreateMachineId(hqRoot)`: machine-id * resolves `HQ_MACHINE_ID` → `/.hq/machine-id` → menubar `machineId` → * autogen, and tier 2 wins before menubar ever gets a look-in. On a real * install the two diverge (observed: enrolled `e1bff370-…` from menubar vs * `/.hq/machine-id` `e3ef5a5a-…`), which is exactly the 403. * * It is also NOT `cli-client-health.json`. That file is the hq-CLI's own * separate enrolled installation (`hq-cli/src/utils/client-health.ts`, * `CLIENT_HEALTH_STATE_FILE`); the CLI and the desktop are two distinct * installations of one person and each enrols under its own id. The runner * stamps `source: "desktop"`, so it must carry the DESKTOP id. * * DISCIPLINE * ---------- * Strictly READ-ONLY. This module never creates, mints, migrates or rewrites * the client-health state file. Minting an id here would (a) be unenrolled by * construction, and (b) risk clobbering the heartbeat's own identity, which * would orphan every previously-reported snapshot. It never throws: a missing, * unreadable, malformed or non-conforming file is simply "no enrolled identity * known", and the caller skips the upload. */ /** * The desktop app's client-health state file. Note the absence of the `cli-` * prefix: `cli-client-health.json` is a DIFFERENT file owned by hq-cli for its * own separately-enrolled installation. */ export declare const DESKTOP_CLIENT_HEALTH_STATE_FILE = "client-health.json"; export interface ReadDesktopInstallationIdOptions { /** The runner's state dir (`HQ_STATE_DIR`-aware). */ stateDir: string; /** Injected home dir. Tests pin it; production reads `os.homedir()`. */ homeDir?: string; } /** * The enrolled desktop installation id for this host, or `undefined` when no * client-health heartbeat has ever pinned one. * * Never throws and never writes. */ export declare function readDesktopInstallationId(options: ReadDesktopInstallationIdOptions): string | undefined; //# sourceMappingURL=sync-runner-installation-id.d.ts.map