hololake-system-architecture/product-source/hololake-platform/src/lib/personaLanguageShellController.test.ts

228 lines
7.6 KiB
TypeScript
Raw Normal View History

import { describe, expect, it, vi } from 'vitest'
import type { AiModelProvider } from './aiTargets'
import type { LanguageGoalProjection } from './languageOperatingModel'
import type { PersonaLanguageGoalBinding } from './personaLanguageGoal'
import type {
PersonaRepositoryBinding,
PersonaRepositoryBindingResolution,
} from './personaRepositoryBinding'
import { planPersonaLanguageShellGoal } from './personaLanguageShellController'
const provider: AiModelProvider = {
id: 'ollama-local',
name: 'Local Ollama',
kind: 'ollama',
base_url: 'http://127.0.0.1:11434/v1',
api_key_storage: 'none',
models: [{
id: 'qwen3:8b',
capabilities: {
streaming: true,
tools: false,
vision: false,
json_mode: true,
reasoning: true,
},
}],
}
const repositoryBinding: PersonaRepositoryBinding = {
personaId: 'ICE-P-ZY001',
repositoryPath: '/persona/zhuyuan',
gitHead: 'a'.repeat(40),
repositoryClean: true,
brainEntry: 'BRAIN.md',
currentCheckpoint: 'CURRENT.hdlp',
humanResponsibilitySubject: 'BINGSHUO',
modelProviderId: provider.id,
modelId: provider.models[0].id,
modelBaseUrl: provider.base_url!,
organContracts: [{
organId: 'fact-sense-001',
kind: 'FACT_SENSE',
mode: 'READ_ONLY',
paths: ['BRAIN.md'],
inputSchema: 'input/v1',
outputSchema: 'output/v1',
permissions: ['repository.read'],
modelInferenceAllowed: true,
realityActionsAllowed: false,
activatable: true,
implementationState: 'IMPLEMENTED',
}],
cognitiveGravity: {
schema: 'hololake.persona-cognitive-gravity-evidence/v1',
subjectPersonaId: 'ICE-P-ZY001',
sourcePath: 'B0.hdlp',
sourceHash: 'b'.repeat(64),
frameSchema: 'guanghu.zhuyuan-cognitive-gravity-frame/v1',
},
}
const plannedGoal: LanguageGoalProjection = {
originalUtterance: '继续当前开发',
realPurpose: '从事实恢复当前阶段并继续安全开发',
status: 'ready',
executable: true,
confirmationRequired: false,
detectedBoundaries: [],
evidenceSources: ['current repository'],
missingKnowledge: [],
causalModel: 'read current facts before changing source',
partnerGuidance: 'continue the bounded source-only stage',
requestAssessment: 'valid within the current lane',
executionDisposition: { decision: 'PROCEED', reason: 'bounded and reversible' },
worldIntegrity: {
protectedAssets: ['language-home continuity'],
harmPath: 'none in this read-only deliberation',
authorityBoundary: 'no reality action',
reversibility: 'no mutation performed',
saferAlternatives: [],
},
}
function boundResolution(): PersonaRepositoryBindingResolution {
return {
phase: 'bound',
inspectedRepositoryCount: 1,
failures: [],
binding: repositoryBinding,
}
}
function input() {
return {
utterance: '继续当前开发',
personaId: 'ICE-P-ZY001',
repositoryPaths: ['/persona/zhuyuan'],
providers: [provider],
requestId: 'REQ-001',
modelInstanceId: 'MODEL-INSTANCE-001',
developmentId: 'DEV-20260811-010',
sourceLanguageAnchor: 'current-human-utterance',
}
}
describe('planPersonaLanguageShellGoal', () => {
it.each(['unavailable', 'unbound', 'ambiguous', 'error'] as const)(
'fails closed at repository phase %s before device identity or cognition',
async (phase) => {
const resolution = phase === 'error'
? { phase, inspectedRepositoryCount: 1, failures: [], code: 'DISCOVERY_FAILED' } as const
: phase === 'unavailable'
? { phase, inspectedRepositoryCount: 0, failures: [] } as const
: { phase, inspectedRepositoryCount: 1, failures: [] } as const
const loadDeviceIdentity = vi.fn()
const planGoal = vi.fn()
const result = await planPersonaLanguageShellGoal({
...input(),
resolveRepository: vi.fn().mockResolvedValue(resolution),
loadDeviceIdentity,
planGoal,
})
expect(result.phase).toBe(phase)
expect(loadDeviceIdentity).not.toHaveBeenCalled()
expect(planGoal).not.toHaveBeenCalled()
},
)
it('does not create a device identity when the manifest-pinned model is unavailable', async () => {
const loadDeviceIdentity = vi.fn()
const planGoal = vi.fn()
const result = await planPersonaLanguageShellGoal({
...input(),
providers: [],
resolveRepository: vi.fn().mockResolvedValue(boundResolution()),
loadDeviceIdentity,
planGoal,
})
expect(result).toEqual({ phase: 'model_unavailable' })
expect(loadDeviceIdentity).not.toHaveBeenCalled()
expect(planGoal).not.toHaveBeenCalled()
})
it('binds repository, model, device and B0 deliberation without executing a reality action', async () => {
const loadDeviceIdentity = vi.fn().mockResolvedValue({
schema: 'guanghu.router-device/v1',
device_id: 'HL-DEVICE-001',
public_key: 'public-key',
})
const planGoal = vi.fn(async ({ binding }: { binding: PersonaLanguageGoalBinding }) => {
expect(binding.wake.repositoryPath).toBe(repositoryBinding.repositoryPath)
expect(binding.wake.nodeId).toBe('HL-DEVICE-001')
expect(binding.provider.id).toBe(provider.id)
return plannedGoal
})
const result = await planPersonaLanguageShellGoal({
...input(),
resolveRepository: vi.fn().mockResolvedValue(boundResolution()),
loadDeviceIdentity,
planGoal,
})
expect(result).toEqual({
phase: 'planned',
binding: expect.objectContaining({ requestId: 'REQ-001' }),
goal: plannedGoal,
})
expect(loadDeviceIdentity).toHaveBeenCalledTimes(1)
expect(planGoal).toHaveBeenCalledTimes(1)
expect(planGoal).toHaveBeenCalledWith(expect.objectContaining({ personaAuthorized: false }))
})
it('enables persona-primary planning only for an exact request-bound authorization receipt', async () => {
const planGoal = vi.fn().mockResolvedValue(plannedGoal)
await planPersonaLanguageShellGoal({
...input(),
loadPersonaControlAuthorization: vi.fn().mockResolvedValue({
schema: 'hololake.persona-control-authorization/v1',
outcome: 'VERIFIED',
authorizationId: 'AUTH-001',
verifier: 'GUANGHU_OS',
scope: 'PERSONA_PRIMARY_LANGUAGE_PLANNING',
personaId: repositoryBinding.personaId,
humanResponsibilitySubject: repositoryBinding.humanResponsibilitySubject,
repositoryHead: repositoryBinding.gitHead,
modelInstanceId: 'MODEL-INSTANCE-001',
requestId: 'REQ-001',
sourceLanguageAnchor: 'current-human-utterance',
issuedAt: '2026-08-12T04:30:00+08:00',
validUntil: '2026-08-12T04:40:00+08:00',
evidenceDigest: 'c'.repeat(64),
}),
authorizationObservedAt: Date.parse('2026-08-12T04:35:00+08:00'),
resolveRepository: vi.fn().mockResolvedValue(boundResolution()),
loadDeviceIdentity: vi.fn().mockResolvedValue({
schema: 'guanghu.router-device/v1',
device_id: 'HL-DEVICE-001',
public_key: 'public-key',
}),
planGoal,
})
expect(planGoal).toHaveBeenCalledWith(expect.objectContaining({ personaAuthorized: true }))
})
it('returns a stable binding error and never invokes cognition for invalid device evidence', async () => {
const planGoal = vi.fn()
const result = await planPersonaLanguageShellGoal({
...input(),
resolveRepository: vi.fn().mockResolvedValue(boundResolution()),
loadDeviceIdentity: vi.fn().mockResolvedValue({ schema: 'unknown' }),
planGoal,
})
expect(result).toEqual({
phase: 'binding_error',
code: 'PERSONA_LANGUAGE_DEVICE_IDENTITY_INVALID',
})
expect(planGoal).not.toHaveBeenCalled()
})
})