← back to PrimeLocus__bmo

Function bodies 413 total

All specs Real LLM only Function bodies
rerank method · typescript · L195-L221 (27 LOC)
beau-terminal/src/lib/server/memory/retriever.ts
	private rerank(fragments: MemoryFragment[]): MemoryFragment[] {
		const now = Date.now();

		for (const frag of fragments) {
			// Base: 1 - distance (ChromaDB L2 normalized cosine → lower distance = more similar)
			const baseSimilarity = 1 - frag.rawDistance;

			// Freshness bonus: recent docs get up to MAX_FRESHNESS_BONUS
			let freshnessBonus = 0;
			if (frag.createdAt) {
				const ageMs = now - new Date(frag.createdAt).getTime();
				if (ageMs >= 0 && ageMs < FRESHNESS_WINDOW_MS) {
					const recency = 1 - ageMs / FRESHNESS_WINDOW_MS;
					freshnessBonus = Math.min(MAX_FRESHNESS_BONUS, recency * MAX_FRESHNESS_BONUS);
				}
			}

			// Identity source prior
			const identityBonus = frag.collection === 'beau_identity' ? IDENTITY_SOURCE_BONUS : 0;

			frag.finalScore = baseSimilarity + freshnessBonus + identityBonus;
		}

		// Sort descending by finalScore
		fragments.sort((a, b) => b.finalScore - a.finalScore);
		return fragments;
	}
trimToBudget method · typescript · L224-L235 (12 LOC)
beau-terminal/src/lib/server/memory/retriever.ts
	private trimToBudget(fragments: MemoryFragment[], maxTokens: number): MemoryFragment[] {
		const result: MemoryFragment[] = [];
		let used = 0;

		for (const frag of fragments) {
			if (used + frag.tokenCount > maxTokens) continue;
			result.push(frag);
			used += frag.tokenCount;
		}

		return result;
	}
buildProvenance method · typescript · L238-L254 (17 LOC)
beau-terminal/src/lib/server/memory/retriever.ts
	private buildProvenance(
		ranked: MemoryFragment[],
		selectedIds: Set<string>,
	): RetrievalProvenance[] {
		return ranked.map((frag, index) => ({
			fragmentId: frag.id,
			collection: frag.collection,
			sourceType: frag.source,
			sourceEntityId: frag.entityId,
			rank: index,
			baseScore: 1 - frag.rawDistance,
			finalScore: frag.finalScore,
			selected: selectedIds.has(frag.id),
			tokenCount: frag.tokenCount,
			excerptHash: createHash('sha256').update(frag.text).digest('hex'),
		}));
	}
collectionForSource function · typescript · L58-L60 (3 LOC)
beau-terminal/src/lib/server/memory/types.ts
export function collectionForSource(source: SourceType): CollectionName {
	return SOURCE_TO_COLLECTION[source];
}
estimateTokens function · typescript · L89-L91 (3 LOC)
beau-terminal/src/lib/server/memory/types.ts
export function estimateTokens(text: string): number {
	return Math.ceil(text.length / 4);
}
formatFragments function · typescript · L94-L96 (3 LOC)
beau-terminal/src/lib/server/memory/types.ts
export function formatFragments(fragments: MemoryFragment[]): string {
	return fragments.map((f) => `[${f.source}] ${f.text}`).join('\n');
}
subscribeToState function · typescript · L142-L146 (5 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
export function subscribeToState(fn: (state: BeauState) => void) {
  listeners.add(fn);
  fn({ ...state });
  return () => listeners.delete(fn);
}
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
getState function · typescript · L148-L150 (3 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
export function getState(): BeauState {
  return { ...state };
}
patchState function · typescript · L153-L156 (4 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
export function patchState(patch: Partial<BeauState>) {
  state = { ...state, ...patch };
  broadcast();
}
broadcast function · typescript · L158-L160 (3 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
function broadcast() {
  for (const fn of listeners) fn({ ...state });
}
publishToMQTT function · typescript · L164-L166 (3 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
export function publishToMQTT(topic: string, message: string) {
  _publish?.(topic, message);
}
backfillDispatcherLog function · typescript · L168-L185 (18 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
function backfillDispatcherLog() {
  try {
    const recent = db.select({ querySummary: dispatches.querySummary })
      .from(dispatches)
      .orderBy(desc(dispatches.id))
      .limit(100)
      .all()
      .reverse();
    state = {
      ...state,
      dispatcherLog: recent
        .filter((r) => r.querySummary)
        .map((r) => r.querySummary as string),
    };
  } catch (err) {
    console.warn('[bridge] dispatcher backfill skipped:', (err as Error).message);
  }
}
logEnvironmentEvent function · typescript · L190-L198 (9 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
function logEnvironmentEvent(eventType: string, payload: Record<string, unknown>, source: string) {
  try {
    db.insert(environmentEvents).values({
      eventType,
      payloadJson: JSON.stringify(payload),
      source,
    }).run();
  } catch { /* non-fatal */ }
}
maybeWriteSnapshot function · typescript · L200-L215 (16 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
function maybeWriteSnapshot() {
  const now = Date.now();
  if (now - lastSnapshotTime < SNAPSHOT_MIN_INTERVAL) return;
  lastSnapshotTime = now;
  try {
    db.insert(environmentSnapshots).values({
      presenceState: state.presenceState || null,
      occupancyConfidence: null,
      lux: state.lux,
      sleepState: state.sleepState || null,
      weatherJson: state.weather ? JSON.stringify(state.weather) : null,
      seasonalSummary: state.seasonalContext || null,
      contextMode: state.mode || null,
    }).run();
  } catch { /* non-fatal */ }
}
vectorToEmotionalState function · typescript · L415-L420 (6 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
  function vectorToEmotionalState(v: { wonder: number; reflection: number; mischief: number }): string {
    const dominant = Math.max(v.wonder, v.reflection, v.mischief);
    if (dominant === v.reflection) return dominant > 0.6 ? 'reflective' : 'contemplative';
    if (dominant === v.mischief) return dominant > 0.6 ? 'mischievous' : 'playful';
    return dominant > 0.6 ? 'wonder' : 'curious';
  }
Repobility (the analyzer behind this table) · https://repobility.com
updateFaceState function · typescript · L430-L437 (8 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
  function updateFaceState() {
    const faceState = resolveFaceState(state, interactionSignals);
    const glow = resolveGlowWithOverlay(faceState, thoughtQueue.getReadyThoughtType());
    state = { ...state, faceState, glow };
    // Note: do NOT call broadcast() here — the MQTT message handler's
    // existing broadcast() at the end of the switch handles it.
    // For personality engine calls, broadcast() is called after state assignment.
  }
refreshActivityCache function · typescript · L449-L478 (30 LOC)
beau-terminal/src/lib/server/mqtt/bridge.ts
  function refreshActivityCache() {
    const cutoff30min = new Date(Date.now() - 30 * 60 * 1000);
    const cutoffText = cutoff30min.toISOString().replace('T', ' ').slice(0, 19);
    try {
      // haikus.createdAt is integer (timestamp mode) — compare with Date object
      activityCache.haikuRecent = !!db.select({ id: haikus.id })
        .from(haikus).where(gte(haikus.createdAt, cutoff30min)).limit(1).get();

      // journalEntries.createdAt is text (datetime format)
      activityCache.journalRecent = !!db.select({ id: journalEntries.id })
        .from(journalEntries).where(gte(journalEntries.createdAt, cutoffText)).limit(1).get();

      // dispatches.createdAt is text (datetime format)
      activityCache.dispatchRecent = !!db.select({ id: dispatches.id })
        .from(dispatches).where(gte(dispatches.createdAt, cutoffText)).limit(1).get();

      // ideas table has no timestamp column — always false
      activityCache.ideaRecent = false;

      // noticings.createdAt is tex
isNotable function · typescript · L43-L65 (23 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
export function isNotable(
	vector: PersonalityVector,
	previousVector: PersonalityVector,
	hasCreativeActivity: boolean,
	hadModeTransition: boolean,
): boolean {
	// Extreme state check
	const dims: (keyof PersonalityVector)[] = ['wonder', 'reflection', 'mischief'];
	for (const dim of dims) {
		if (vector[dim] > 0.85 || vector[dim] < 0.15) return true;
	}

	// Large delta check
	for (const dim of dims) {
		if (Math.abs(vector[dim] - previousVector[dim]) > 0.2) return true;
	}

	// Activity / transition flags
	if (hasCreativeActivity) return true;
	if (hadModeTransition) return true;

	return false;
}
getRetentionTier function · typescript · L75-L81 (7 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
export function getRetentionTier(timestamp: Date, now: Date): RetentionTier {
	const ageMs = now.getTime() - timestamp.getTime();
	if (ageMs < TIER_HOT_MS)  return 'hot';
	if (ageMs < TIER_WARM_MS) return 'warm';
	if (ageMs < TIER_COOL_MS) return 'cool';
	return 'cold';
}
toSQLiteTs function · typescript · L86-L88 (3 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
function toSQLiteTs(d: Date): string {
	return d.toISOString().replace('T', ' ').slice(0, 19);
}
runCompaction function · typescript · L105-L210 (106 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
export function runCompaction(db: DrizzleDB): void {
	const now = new Date();
	const hotCutoff  = new Date(now.getTime() - TIER_HOT_MS);
	const warmCutoff = new Date(now.getTime() - TIER_WARM_MS);
	const coolCutoff = new Date(now.getTime() - TIER_COOL_MS);

	const hotCutoffTs  = toSQLiteTs(hotCutoff);
	const warmCutoffTs = toSQLiteTs(warmCutoff);
	const coolCutoffTs = toSQLiteTs(coolCutoff);

	// ── warm tier: keep hourly peaks ─────────────────────────────────────────
	// Fetch all non-notable warm-tier rows
	const warmRows = db.select({
		id: personalitySnapshots.id,
		timestamp: personalitySnapshots.timestamp,
		wonder: personalitySnapshots.wonder,
		reflection: personalitySnapshots.reflection,
		mischief: personalitySnapshots.mischief,
	})
	.from(personalitySnapshots)
	.where(
		and(
			lt(personalitySnapshots.timestamp, hotCutoffTs),
			gte(personalitySnapshots.timestamp, warmCutoffTs),
			eq(personalitySnapshots.isNotable, 0),
		),
	)
	.all();

	// Group by hour, identify peak (h
exportPersonalityTimeline function · typescript · L239-L277 (39 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
export function exportPersonalityTimeline(db: DrizzleDB, outputPath: string): void {
	const { writeFileSync } = await_import_sync();

	const now = new Date();
	const rows = db.select().from(personalitySnapshots).all();

	const tierCounts: TierCounts = { hot: 0, warm: 0, cool: 0, cold: 0 };
	const snapshots = rows.map((row) => {
		const tier = getRetentionTier(new Date(row.timestamp), now);
		tierCounts[tier]++;
		return {
			id:               row.id,
			timestamp:        row.timestamp,
			tier,
			wonder:           row.wonder,
			reflection:       row.reflection,
			mischief:         row.mischief,
			derivedMode:      row.derivedMode,
			interpretation:   row.interpretation ?? null,
			isNotable:        row.isNotable,
			snapshotReason:   row.snapshotReason,
		};
	});

	const dateStr = now.toISOString().slice(0, 10);
	const filename = `personality-export-${dateStr}.json`;
	const fullPath = join(outputPath, filename);

	mkdirSync(outputPath, { recursive: true });

	const payload: Person
await_import_sync function · typescript · L283-L287 (5 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
function await_import_sync() {
	// eslint-disable-next-line @typescript-eslint/no-require-imports
	const { writeFileSync } = require('fs') as typeof import('fs');
	return { writeFileSync };
}
Want this analysis on your repo? https://repobility.com/scan/
scheduleBackup function · typescript · L299-L322 (24 LOC)
beau-terminal/src/lib/server/personality/compaction.ts
export function scheduleBackup(
	sqliteInstance: { backup: (destination: string) => Promise<void> },
	backupPath: string,
	intervalMs: number,
): () => void {
	mkdirSync(backupPath, { recursive: true });

	const doBackup = async () => {
		const now = new Date();
		const dateStr = now.toISOString().slice(0, 10);                   // YYYY-MM-DD
		const hour    = now.toISOString().slice(11, 13);                  // HH
		const filename = `beau-backup-${dateStr}-${hour}.db`;
		const filepath = join(backupPath, filename);
		try {
			await sqliteInstance.backup(filepath);
		} catch (err) {
			console.error('[personality/compaction] Backup failed:', err);
		}
	};

	const handle = setInterval(doBackup, intervalMs);

	return () => clearInterval(handle);
}
envelopeDistance function · typescript · L33-L38 (6 LOC)
beau-terminal/src/lib/server/personality/discomfort.ts
export function envelopeDistance(v: PersonalityVector, env: ModeEnvelope): number {
	const dW = Math.max(0, env.wonder.min - v.wonder, v.wonder - env.wonder.max);
	const dR = Math.max(0, env.reflection.min - v.reflection, v.reflection - env.reflection.max);
	const dM = Math.max(0, env.mischief.min - v.mischief, v.mischief - env.mischief.max);
	return Math.sqrt(dW * dW + dR * dR + dM * dM);
}
findDominantDeviation function · typescript · L45-L48 (4 LOC)
beau-terminal/src/lib/server/personality/discomfort.ts
export function findDominantDeviation(
	v: PersonalityVector,
	env: ModeEnvelope,
): { dimension: 'wonder' | 'reflection' | 'mischief'; distance: number; sign: -1 | 1 } | null {
computeDiscomfort function · typescript · L69-L73 (5 LOC)
beau-terminal/src/lib/server/personality/discomfort.ts
export function computeDiscomfort(envDistance: number, persistenceMs: number): number {
	const envComponent = Math.min(1.0, envDistance / ENVELOPE_DISTANCE_CAP);
	const persComponent = Math.min(1.0, persistenceMs / PERSISTENCE_CAP_MS);
	return ENVELOPE_WEIGHT * envComponent + PERSISTENCE_WEIGHT * persComponent;
}
computeEnvelopeDistanceWithGrace function · typescript · L81-L94 (14 LOC)
beau-terminal/src/lib/server/personality/discomfort.ts
export function computeEnvelopeDistanceWithGrace(
	vector: PersonalityVector,
	currentMode: string,
	candidateMode: string | null,
): number {
	const currentEnv = MODE_ENVELOPES[currentMode];
	if (!currentEnv) return 0;
	const currentDist = envelopeDistance(vector, currentEnv);
	if (candidateMode) {
		const candidateEnv = MODE_ENVELOPES[candidateMode];
		if (candidateEnv) return Math.min(currentDist, envelopeDistance(vector, candidateEnv));
	}
	return currentDist;
}
createDiscomfortState function · typescript · L99-L110 (12 LOC)
beau-terminal/src/lib/server/personality/discomfort.ts
export function createDiscomfortState(): DiscomfortState {
	return {
		score: 0,
		envelopeDistance: 0,
		persistenceMs: 0,
		coefficient: 1.0,
		dominantDimension: null,
		consecutiveHighTicks: 0,
		consecutiveLowTicks: 0,
		peakCoefficient: 1.0,
	};
}
updateDiscomfortState function · typescript · L116-L154 (39 LOC)
beau-terminal/src/lib/server/personality/discomfort.ts
export function updateDiscomfortState(
	state: DiscomfortState,
	vector: PersonalityVector,
	currentMode: string,
	candidateMode: string | null,
	tickMs: number,
): void {
	// 1. Envelope distance (with grace for pending mode transitions)
	state.envelopeDistance = computeEnvelopeDistanceWithGrace(vector, currentMode, candidateMode);

	// 2. Persistence accumulation
	if (state.envelopeDistance > 0) {
		state.persistenceMs += tickMs;
	} else {
		state.persistenceMs = 0;
	}

	// 3. Composite discomfort score
	state.score = computeDiscomfort(state.envelopeDistance, state.persistenceMs);

	// 4. Dominant dimension
	const currentEnv = MODE_ENVELOPES[currentMode];
	if (currentEnv) {
		const dom = findDominantDeviation(vector, currentEnv);
		state.dominantDimension = dom?.dimension ?? null;
	}

	// 5. Consecutive tick counters
	state.consecutiveHighTicks = state.score > 0.5 ? state.consecutiveHighTicks + 1 : 0;
	state.consecutiveLowTicks = state.score < 0.1 ? state.consecutiveLowTicks + 1 : 0;
cloneVec function · typescript · L55-L57 (3 LOC)
beau-terminal/src/lib/server/personality/engine.ts
function cloneVec(v: PersonalityVector): PersonalityVector {
	return { wonder: v.wonder, reflection: v.reflection, mischief: v.mischief };
}
Repobility · code-quality intelligence platform · https://repobility.com
maxDelta function · typescript · L59-L65 (7 LOC)
beau-terminal/src/lib/server/personality/engine.ts
function maxDelta(a: PersonalityVector, b: PersonalityVector): number {
	return Math.max(
		Math.abs(a.wonder - b.wonder),
		Math.abs(a.reflection - b.reflection),
		Math.abs(a.mischief - b.mischief),
	);
}
PersonalityEngine class · typescript · L67-L259 (193 LOC)
beau-terminal/src/lib/server/personality/engine.ts
export class PersonalityEngine {
	private config: EngineConfig;
	private signal: PersonalityVector;
	private momentum: PersonalityVector;
	private output: PersonalityVector;
	private classifier: ModeClassifier;
	private interpretation = '';
	private listeners: Array<(v: PersonalityVector) => void> = [];
	private lastSnapshot: EngineSnapshot | null = null;
	private lastSnapshotOutput: PersonalityVector;
	private tickCount = 0;
	private intervalId: ReturnType<typeof setInterval> | null = null;
	private discomfortState: DiscomfortState;
	private lastSelfRegResult: SelfRegulationResult | null = null;

	constructor(config: Partial<EngineConfig> = {}) {
		this.config = { ...DEFAULT_CONFIG, ...config };
		const baseline = cloneVec(this.config.restingBaseline);
		this.signal = cloneVec(baseline);
		this.momentum = cloneVec(baseline);
		this.output = cloneVec(baseline);
		this.lastSnapshotOutput = cloneVec(baseline);
		this.classifier = new ModeClassifier();
		this.discomfortState = createDisco
constructor method · typescript · L82-L91 (10 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	constructor(config: Partial<EngineConfig> = {}) {
		this.config = { ...DEFAULT_CONFIG, ...config };
		const baseline = cloneVec(this.config.restingBaseline);
		this.signal = cloneVec(baseline);
		this.momentum = cloneVec(baseline);
		this.output = cloneVec(baseline);
		this.lastSnapshotOutput = cloneVec(baseline);
		this.classifier = new ModeClassifier();
		this.discomfortState = createDiscomfortState();
	}
tick method · typescript · L95-L192 (98 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	tick(sensor: SensorState, activity: ActivitySignals): void {
		const targets = computeSignalTargets(sensor, activity);
		const cfg = this.config;
		const alphas = cfg.signalAlphas;

		// (a.5) Self-regulation controller (uses previous tick's output as the vector to evaluate)
		const selfReg = computeSelfRegulation(this.output, this.classifier.currentMode, this.discomfortState);
		this.lastSelfRegResult = selfReg;

		// Merge self-regulation deltas into targets, re-clamp to [0, 1]
		targets.wonder     = Math.max(0, Math.min(1, targets.wonder     + selfReg.deltas.wonder));
		targets.reflection = Math.max(0, Math.min(1, targets.reflection + selfReg.deltas.reflection));
		targets.mischief   = Math.max(0, Math.min(1, targets.mischief   + selfReg.deltas.mischief));
		targets.sources.push(...selfReg.sources);

		// (a) EMA: signal layer toward targets
		this.signal.wonder     = (1 - alphas.wonder)     * this.signal.wonder     + alphas.wonder     * targets.wonder;
		this.signal.reflection = (
start method · typescript · L196-L204 (9 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	start(
		getSensor: () => SensorState,
		getActivity: () => ActivitySignals,
	): void {
		if (this.intervalId) return;
		this.intervalId = setInterval(() => {
			this.tick(getSensor(), getActivity());
		}, this.config.tickInterval);
	}
stop method · typescript · L206-L211 (6 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	stop(): void {
		if (this.intervalId) {
			clearInterval(this.intervalId);
			this.intervalId = null;
		}
	}
onVectorChange method · typescript · L221-L223 (3 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	onVectorChange(callback: (vector: PersonalityVector) => void): void {
		this.listeners.push(callback);
	}
getLastSnapshot method · typescript · L225-L229 (5 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	getLastSnapshot(): EngineSnapshot | null {
		const s = this.lastSnapshot;
		this.lastSnapshot = null; // consume — bridge reads once then clears
		return s;
	}
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
getDiscomfortState method · typescript · L231-L233 (3 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	getDiscomfortState(): DiscomfortState {
		return { ...this.discomfortState };
	}
getLastSelfRegResult method · typescript · L235-L237 (3 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	getLastSelfRegResult(): SelfRegulationResult | null {
		return this.lastSelfRegResult;
	}
resetSelfReflectionTrigger method · typescript · L239-L241 (3 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	resetSelfReflectionTrigger(): void {
		this.discomfortState.consecutiveHighTicks = 0;
	}
restoreMomentum method · typescript · L245-L247 (3 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	restoreMomentum(vector: PersonalityVector): void {
		this.momentum = cloneVec(vector);
	}
forceMode method · typescript · L249-L253 (5 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	forceMode(mode: string, reason: string): void {
		console.warn(`[PersonalityEngine] forceMode(${mode}) — reason: ${reason}`);
		this.classifier.previousMode = this.classifier.currentMode;
		this.classifier.currentMode = mode;
	}
reflect method · typescript · L255-L258 (4 LOC)
beau-terminal/src/lib/server/personality/engine.ts
	async reflect(): Promise<null> {
		// TODO-B: LLM reflection will replace this — see §17 of beaus-bible.md
		return null;
	}
getTier function · typescript · L116-L121 (6 LOC)
beau-terminal/src/lib/server/personality/interpreter.ts
function getTier(value: number): Tier {
	if (value < 0.25) return 'quiet';
	if (value < 0.5)  return 'present';
	if (value < 0.75) return 'strong';
	return 'intense';
}
pick function · typescript · L128-L134 (7 LOC)
beau-terminal/src/lib/server/personality/interpreter.ts
function pick<T>(pool: readonly T[], vector: PersonalityVector, salt: number = 0): T {
	const hash = Math.floor(
		(vector.wonder * 1000 + vector.reflection * 100 + vector.mischief * 10 + salt) % pool.length,
	);
	const idx = Math.abs(hash) % pool.length;
	return pool[idx];
}
Repobility (the analyzer behind this table) · https://repobility.com
selectSelfRegPhrase function · typescript · L141-L163 (23 LOC)
beau-terminal/src/lib/server/personality/interpreter.ts
function selectSelfRegPhrase(ctx: SelfRegContext, vector: PersonalityVector): string | null {
	if (ctx.recentlySettled) {
		return pick(SELF_REG_PHRASES['settled'], vector, 10);
	}

	if (ctx.sustainedEase) {
		return pick(SELF_REG_PHRASES['at-ease'], vector, 11);
	}

	if (ctx.discomfort > 0.4 && ctx.dominantDimension) {
		const key = `settling-${ctx.dominantDimension}` as keyof typeof SELF_REG_PHRASES;
		if (key in SELF_REG_PHRASES) {
			return pick(SELF_REG_PHRASES[key], vector, 12);
		}
	}

	// Staying-elevated: outside envelope for >1 min but coefficient hasn't escalated
	if (ctx.discomfort > 0.3 && ctx.persistenceMs > 60000 && ctx.coefficient < 1.3) {
		return pick(SELF_REG_PHRASES['staying-elevated'], vector, 13);
	}

	return null;
}
interpretVector function · typescript · L173-L228 (56 LOC)
beau-terminal/src/lib/server/personality/interpreter.ts
export function interpretVector(
	vector: PersonalityVector,
	mode: string,         // e.g. 'ambient', 'archivist', 'social', 'witness'
	sensor: SensorState,
	sources: string[],    // e.g. ['time:late-night', 'weather:storm']
	selfReg?: SelfRegContext,
): string {
	// 1. Find dominant dimension
	const dims: [Dimension, number][] = [
		['wonder',     vector.wonder],
		['reflection', vector.reflection],
		['mischief',   vector.mischief],
	];
	dims.sort((a, b) => b[1] - a[1]);
	const [dominantDim, dominantVal] = dims[0];
	const dominantTier = getTier(dominantVal);

	// 2. Opening sentence from dominant pool
	const openingPool = PHRASES[dominantDim][dominantTier];
	const opening = pick(openingPool, vector, 0);

	// 3. Secondary color — pick the first non-dominant dim above 'present'
	let secondary: string | null = null;
	for (const [dim, val] of dims.slice(1)) {
		if (val >= 0.25) {
			const secPool = SECONDARY[dim];
			secondary = pick(secPool, vector, 1);
			break;
		}
	}

	// 4. Context
distance function · typescript · L29-L35 (7 LOC)
beau-terminal/src/lib/server/personality/mode-classifier.ts
function distance(a: PersonalityVector, b: PersonalityVector): number {
	return Math.sqrt(
		(a.wonder - b.wonder) ** 2 +
		(a.reflection - b.reflection) ** 2 +
		(a.mischief - b.mischief) ** 2,
	);
}
‹ prevpage 4 / 9next ›