/** * User-profile CRUD operations for the NEXUS user_profile table. * * Provides the 5 SDK functions for PSYCHE Wave 1 (T1078): * - getUserProfileTrait — fetch a single trait by key * - upsertUserProfileTrait — create-or-update a trait * - reinforceTrait — increment reinforcement count + bump confidence * - listUserProfile — list all traits (with optional confidence filter) * - supersedeTrait — mark one trait as superseded by another * * All functions accept a `nexusDb` argument (NodeSQLiteDatabase) * to keep them unit-testable without touching the real nexus.db singleton. * Callers that do not need test isolation may use `getNexusDb()` from * `packages/core/src/store/nexus-sqlite.ts` directly. * * PSYCHE reference: `upstream psyche-lineage · crud/peer.py` (getOrCreate + * metadata merge pattern) and `models.py` (User metadata attributes). * * @task T1078 * @epic T1076 */ import type { NexusProfileExportResult, NexusProfileGetResult, NexusProfileImportResult, NexusProfileReinforceResult, NexusProfileSupersedeResult, NexusProfileUpsertResult, NexusProfileViewResult, UserProfileScope, UserProfileTrait } from '@cleocode/contracts'; import type { NodeSQLiteDatabase } from 'drizzle-orm/node-sqlite'; import { type EngineResult } from '../engine-result.js'; /** Type alias for the Drizzle nexus database instance. */ type NexusDb = NodeSQLiteDatabase; /** * Resolve the portable project id a trait derived under `projectRoot` is * stamped with (T12543). * * Uses the tracked write-once `.cleo/project-id` (ADR-094) and falls back to * the `projectId` in `.cleo/project-info.json`. Never derives an id from the * path: a path hash differs per checkout and device, so it would silently * re-scope traits. Returns `null` when neither identity is readable — the * caller then records the trait as unknown-origin (never shown in prompts). * * @param projectRoot - Absolute project root the trait was derived in. * @returns The portable project id, or `null` when none is declared. * * @example * ```ts * const projectId = resolveTraitProjectId('/work/cleocode'); // 'c78d09c3a8ee' * ``` * * @task T12543 */ export declare function resolveTraitProjectId(projectRoot: string): string | null; /** * Fetch a single user-profile trait by its key. * * Returns `null` when no matching row exists. * * @param nexusDb - Drizzle nexus database handle. * @param traitKey - Semantic trait key to look up. * @returns The matching `UserProfileTrait`, or `null`. */ export declare function getUserProfileTrait(nexusDb: NexusDb, traitKey: string): Promise; /** * Create or update a user-profile trait. * * When a row with the same `traitKey` already exists it is overwritten * in full — this is the "last writer wins" semantics used by `importUserProfile` * after the conflict-resolution step (higher confidence wins, see T1079). * The `firstObservedAt` field is preserved from the existing row on update. * * @param nexusDb - Drizzle nexus database handle. * `projectId` and `scope` (T12543) default to `null` (unknown origin) and * `'project'`; the whole row — value and visibility — is replaced together. * A `project`-scoped write never replaces an existing `user`-scoped row. * * @param trait - Trait to insert or replace. `firstObservedAt` and * `lastReinforcedAt` should be ISO 8601 strings; they are * stored as canonical TEXT ISO-8601 in the consolidated * `nexus_user_profile` table (T11578 · AC3). */ export declare function upsertUserProfileTrait(nexusDb: NexusDb, trait: UserProfileTrait): Promise; /** * Explicitly set the visibility scope of an existing trait (T12543). * * The only path that can promote a trait to user-global (`user`, visible in * every project) or demote one back to `project`. Value, provenance and the * project stamp are unchanged. * * @param nexusDb - Drizzle nexus database handle. * @param traitKey - Key of the trait to re-scope. * @param scope - New scope. * @returns The previous scope, or `null` when no such trait exists. * * @example * ```ts * await setUserProfileTraitScope(db, 'prefers-zero-deps', 'user'); * ``` */ export declare function setUserProfileTraitScope(nexusDb: NexusDb, traitKey: string, scope: UserProfileScope): Promise; /** * Increment the reinforcement count for an existing trait and boost its * confidence. * * Reinforcement boost formula: * newConfidence = existing + (1 − existing) × 0.1 * Each reinforcement moves confidence 10% closer to 1.0 (asymptotic approach). * Capped at 1.0. * * No-ops silently when the traitKey does not exist. * * @param nexusDb - Drizzle nexus database handle. * @param traitKey - Key of the trait to reinforce. * @param source - Source identifier recorded on the update (e.g. "manual"). */ export declare function reinforceTrait(nexusDb: NexusDb, traitKey: string, source: string): Promise; /** * List all user-profile traits, optionally filtered by minimum confidence. * * Only non-superseded traits are returned by default — pass * `opts.includeSuperseded = true` to include deprecated traits. * * @param nexusDb - Drizzle nexus database handle. * @param opts - Optional filtering options. * @returns Array of traits ordered by confidence desc, then traitKey asc. */ export declare function listUserProfile(nexusDb: NexusDb, opts?: { /** Minimum confidence threshold (inclusive). Defaults to 0.0. */ minConfidence?: number; /** Include superseded (deprecated) traits. Defaults to false. */ includeSuperseded?: boolean; /** * Restrict to the traits visible in one project's prompts (T12543): * `user`-scoped traits plus `project` traits stamped with this portable * project id. `null` = the project has no declared identity, so only * user-global traits are returned. Omit to list every row (admin view, * export) — unknown-origin rows included. */ visibleInProject?: string | null; }): Promise; /** * Mark a trait as superseded by another, implementing the T1139 supersession * link for the profile domain. * * The old trait row has its `supersededBy` field set to `newKey`. * The new trait is not modified (it must already exist or be created separately * via `upsertUserProfileTrait`). * * No-ops silently when `oldKey` does not exist. * * @param nexusDb - Drizzle nexus database handle. * @param oldKey - Trait key that is being deprecated. * @param newKey - Trait key that replaces it. */ export declare function supersedeTrait(nexusDb: NexusDb, oldKey: string, newKey: string): Promise; export declare function nexusProfileView(minConfidence?: number, includeSuperseded?: boolean): Promise>; export declare function nexusProfileGet(traitKey: string): Promise>; export declare function nexusProfileImport(path?: string): Promise>; export declare function nexusProfileExport(path?: string): Promise>; export declare function nexusProfileReinforce(traitKey: string, source?: string): Promise>; export declare function nexusProfileUpsert(trait: Pick): Promise>; export declare function nexusProfileSupersede(oldKey: string, newKey: string): Promise>; export {}; //# sourceMappingURL=user-profile.d.ts.map