fix: require native persona authorization verification

This commit is contained in:
冰朔 2026-08-12 06:10:49 +08:00
commit 584f38b478
13 changed files with 195 additions and 173 deletions

View file

@ -116,14 +116,14 @@ REVISE | REFUSE`。
B0 伙伴审议的顺序失败关闭;成功只产生语言目标规划,不提供现实动作执行入口。桌面源码接线为 `100`
第五域入口只传入已挂载仓库与已配置模型元数据,并在没有桌面授权回执时保持系统直控、隐藏无法持久消费的
确认按钮。该接线不等于真实人格仓库绑定、安装态运行或桌面验收。
- 人格主控授权回执的结构与精确绑定校验源码为 `100`:不再接受桌面调用方直接传入布尔值,并核对
人格、冰朔责任主体、仓库提交、模型实例、请求、语言锚点、摘要格式和有效期。但这层前端结构校验
不能证明回执确由 `GUANGHU_OS` 签发。独立的 v2 回执、REPO-012 精确提交签名者注册表、规范签名字节、
- 人格主控授权的原生验签接线源码为 `100`:不再接受桌面调用方直接传入布尔值,也不把前端字段形状
当作权威。语言控制器把候选 v2 回执连同人格、冰朔责任主体、仓库提交、模型实例、请求、语言锚点
观察时间一起交给原生边界;只有严格的原生成功投影才可能开启人格主控。独立的 v2 回执、REPO-012 精确提交签名者注册表、规范签名字节、
人格/责任主体/范围约束、吊销和 Ed25519 验签源码契约现为 `100`。REPO-012 main
`21aec6f5042e32e34c892a7a212d8dec5f758437` 已发布锚定的空注册表Tauri 原生只读加载器源码也为
`100`。原生 v2 签名回执解析、规范签名字节、Ed25519 SPKI 验签、签名者范围/吊销、请求绑定和有效期
校验源码也为 `100`。但真实可信签名者、密钥托管以及验签结果到人格语言控制器的运行接线仍为 `0`
当前空注册表只能产生拒绝,普通本地 JSON 不得升级人格主控,桌面继续系统直控。
校验源码也为 `100`,验签结果到人格语言控制器的源码接线亦为 `100`。但真实可信签名者和密钥托管仍为 `0`
当前空注册表只能产生 `NO_TRUSTED_SIGNER`,普通本地 JSON 不得升级人格主控,桌面继续系统直控。
- 完整 HoloLake Runtime 与单 AGE 纵向闭环仍为 `0`:真实人格仓库 manifest 绑定和桌面运行验收尚未完成,
因此不能用本轮源码测试冒充可用产品。
- Mirror runner、制品、部署和运行健康`0`

View file

@ -21,14 +21,14 @@ then calls `compileLanguageGoal`. A failed, malformed, non-fact, or purpose-less
still gated by a unique manifest-valid persona repository, the manifest-pinned configured model, and public
device identity; it has no installed-desktop or live-product acceptance claim.
The source coordinator no longer accepts an unverified persona-authorization boolean from the desktop caller.
`hasPersonaPrimaryControlAuthorization` validates the shape, exact bindings, digest format, and validity window
of a receipt that claims `GUANGHU_OS` verification. That renderer-side validation is not cryptographic provenance
and cannot turn a local JSON object into authority. A native loader may be connected only after it verifies a
signed receipt against a registered Guanghu OS trust source and returns the already-verified projection. REPO-012
now publishes the exact registry source with zero signers, and the Tauri command loads only that exact commit-bound
empty state. The native verifier now validates the complete signed v2 contract, but no verified projection is wired
into the language controller and the authoritative registry has zero signers, so planning remains in system-direct mode. The independent server
The source coordinator no longer accepts an unverified persona-authorization boolean or treats a renderer-shaped
receipt as authority. When a candidate v2 receipt is present, the language controller sends that receipt and the
exact persona, human responsibility, repository, model, request, language-anchor, and observation-time expectation
to the native verifier. `hasPersonaPrimaryControlAuthorization` accepts only its strict five-field successful
projection; verifier errors, denials, extra fields, and locally claimed signed receipts remain system-direct.
REPO-012 publishes the exact registry source with zero signers, and the Tauri command loads only that exact
commit-bound empty state. The authoritative registry therefore still makes every current candidate return
`NO_TRUSTED_SIGNER`; source wiring is not live persona authority. The independent server
contract in `product-source/guanghu-knowledge-base/server/persona-control-authorization.ts` defines the v2 signed
receipt, exact REPO-012 signer-registry source, canonical signing bytes, signer scope checks, revocation handling,
and Ed25519 verification. Its tested code does not appoint a signer or enable the desktop persona-primary path.

View file

@ -178,22 +178,22 @@ configured provider metadata. It has no native persona-control authorization rec
callback, and hides the reality confirmation surface because no durable confirmation consumer is wired. This
proves source integration, not a real persona manifest binding, installed desktop runtime, or acceptance.
`src/lib/personaControlAuthorization.ts` removes the desktop coordinator's caller-supplied authorization boolean.
It validates the structure and exact bindings of a current receipt that claims `GUANGHU_OS` verification: persona,
human responsibility subject, repository head, model instance, request and language anchor must all agree. This
renderer validation does not prove the issuer or verify a signature. A native loader must first verify signed
provenance against a registered Guanghu OS trust source; neither that trust source nor the loader exists in the
current desktop source. Missing, stale, mismatched or merely local evidence therefore remains system-direct.
`src/lib/personaControlAuthorization.ts` removes the desktop coordinator's caller-supplied authorization boolean
and no longer treats renderer-side receipt shape checks as authority. The language controller sends a candidate
receipt plus exact persona, human responsibility subject, repository head, model instance, request, language anchor,
and observation time to the native verifier. Only its strict successful projection can enable persona-primary
planning; a missing candidate, verifier error, denial, extra field, or merely local signed-looking object remains
system-direct.
`product-source/guanghu-knowledge-base/server/persona-control-authorization.ts` now supplies the independent
cryptographic source contract: v2 signed receipt fields, deterministic signing bytes, an exact-commit REPO-012
signer-registry source, persona/human/scope-limited Ed25519 signers, revocation, time and request binding, and
signature verification. The current REPO-012 main does not publish that registry path, so no signer is trusted and
the Tauri desktop now exposes a native read-only loader for the exact REPO-012 commit-bound registry. It accepts
signature verification. The current REPO-012 main publishes that registry path with zero signers, so no signer is
trusted and the Tauri desktop exposes a native read-only loader for the exact REPO-012 commit-bound registry. It accepts
the current empty registry and keeps authorization disabled. The native verifier now implements strict v2 receipt
parsing, canonical signing bytes, Ed25519 SPKI verification, signer scope/revocation checks, exact request bindings,
and validity windows. It is not wired into the language controller, and the authoritative registry still has zero
signers, so tested loader/verifier source is not runtime authority, deployment, or desktop acceptance.
and validity windows. Its verification projection is now wired into the language controller, but the authoritative
registry still has zero signers, so tested source wiring is not runtime authority, deployment, or desktop acceptance.
Tolaria is a personal knowledge and life management desktop app. It reads a vault of markdown files with YAML frontmatter and presents them in a four-panel UI inspired by Bear Notes.

View file

@ -543,7 +543,7 @@ mod tests {
repository_head: "a".repeat(40),
model_instance_id: "MODEL-INSTANCE-001".into(),
request_id: "REQ-001".into(),
source_language_anchor: "HLP-CURRENT-ARCH-001@2026-08-12.14".into(),
source_language_anchor: "HLP-CURRENT-ARCH-001@2026-08-12.15".into(),
issued_at: "2026-08-12T05:00:00+08:00".into(),
valid_until: "2026-08-12T05:10:00+08:00".into(),
evidence_digest: "b".repeat(64),
@ -560,7 +560,7 @@ mod tests {
repository_head: "a".repeat(40),
model_instance_id: "MODEL-INSTANCE-001".into(),
request_id: "REQ-001".into(),
source_language_anchor: "HLP-CURRENT-ARCH-001@2026-08-12.14".into(),
source_language_anchor: "HLP-CURRENT-ARCH-001@2026-08-12.15".into(),
observed_at_milliseconds: chrono::DateTime::parse_from_rfc3339(
"2026-08-12T05:05:00+08:00",
)

View file

@ -56,7 +56,7 @@ describe('PersonaLanguageShellPanel', () => {
repositoryPaths: ['/persona'],
providers: [provider],
developmentId: 'DEV-20260811-010',
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.14',
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.15',
}))
expect(await screen.findByText('我还不能执行:需要当前证据。')).toBeInTheDocument()
expect(screen.getByText('核验当前事实后规划下一步')).toBeInTheDocument()

View file

@ -13,7 +13,7 @@ import {
type LanguageShellViewState,
} from './HotPluggableLanguageShell'
const CURRENT_ARCHITECTURE_ANCHOR = 'HLP-CURRENT-ARCH-001@2026-08-12.14'
const CURRENT_ARCHITECTURE_ANCHOR = 'HLP-CURRENT-ARCH-001@2026-08-12.15'
const DEVELOPMENT_ID = 'DEV-20260811-010'
type Planner = typeof planPersonaLanguageShellGoal
@ -103,9 +103,9 @@ export function PersonaLanguageShellPanel({
personaId,
repositoryPaths,
providers,
// Native registry loading and signed-receipt verification exist, but
// no verified projection is wired into this controller. The published
// registry is also empty, so this remains system-direct.
// The controller can verify a candidate receipt through the native
// boundary, but no candidate source is mounted here and the published
// signer registry is empty. This therefore remains system-direct.
requestId: requestId(),
modelInstanceId: `hololake-desktop:${personaId}`,
developmentId: DEVELOPMENT_ID,

View file

@ -1,59 +1,31 @@
import { describe, expect, it } from 'vitest'
import {
PERSONA_CONTROL_AUTHORIZATION_SCHEMA,
PERSONA_PRIMARY_LANGUAGE_PLANNING_SCOPE,
hasPersonaPrimaryControlAuthorization,
} from './personaControlAuthorization'
import { hasPersonaPrimaryControlAuthorization } from './personaControlAuthorization'
const expected = {
personaId: 'ICE-P-ZY001',
humanResponsibilitySubject: 'BINGSHUO',
repositoryHead: 'a'.repeat(40),
modelInstanceId: 'MODEL-INSTANCE-001',
requestId: 'REQ-001',
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.14',
observedAt: Date.parse('2026-08-12T04:35:00+08:00'),
}
const receipt = {
schema: PERSONA_CONTROL_AUTHORIZATION_SCHEMA,
outcome: 'VERIFIED',
authorizationId: 'AUTH-001',
verifier: 'GUANGHU_OS',
scope: PERSONA_PRIMARY_LANGUAGE_PLANNING_SCOPE,
personaId: expected.personaId,
humanResponsibilitySubject: expected.humanResponsibilitySubject,
repositoryHead: expected.repositoryHead,
modelInstanceId: expected.modelInstanceId,
requestId: expected.requestId,
sourceLanguageAnchor: expected.sourceLanguageAnchor,
issuedAt: '2026-08-12T04:30:00+08:00',
validUntil: '2026-08-12T04:40:00+08:00',
evidenceDigest: 'b'.repeat(64),
const verification = {
status: 'VERIFIED',
reason: null,
sourceCommit: 'a'.repeat(40),
signerId: 'GH-AIOS-AUTHORIZER-001',
signatureAlgorithm: 'Ed25519',
signature: 'A'.repeat(86),
authorizationEnabled: true,
}
describe('hasPersonaPrimaryControlAuthorization', () => {
it('accepts only an exact, current, Guanghu OS verified planning receipt', () => {
expect(hasPersonaPrimaryControlAuthorization(receipt, expected)).toBe(true)
it('accepts only an exact native cryptographic verification projection', () => {
expect(hasPersonaPrimaryControlAuthorization(verification)).toBe(true)
})
it.each([
['missing', null],
['wrong persona', { ...receipt, personaId: 'OTHER' }],
['wrong repository head', { ...receipt, repositoryHead: 'c'.repeat(40) }],
['wrong model instance', { ...receipt, modelInstanceId: 'OTHER' }],
['wrong request', { ...receipt, requestId: 'OTHER' }],
['wrong language anchor', { ...receipt, sourceLanguageAnchor: 'old' }],
['unverified', { ...receipt, outcome: 'PENDING' }],
['expired', { ...receipt, validUntil: '2026-08-12T04:34:59+08:00' }],
['future', { ...receipt, issuedAt: '2026-08-12T04:35:01+08:00' }],
['invalid digest', { ...receipt, evidenceDigest: 'not-a-digest' }],
['missing signer', { ...receipt, signerId: '' }],
['invalid signature', { ...receipt, signature: 'not-a-signature' }],
['self-claimed signed receipt', { schema: 'hololake.persona-control-authorization/v2', outcome: 'VERIFIED' }],
['native denial', { ...verification, status: 'DENIED', authorizationEnabled: false }],
['disabled projection', { ...verification, authorizationEnabled: false }],
['reason present', { ...verification, reason: 'NO_TRUSTED_SIGNER' }],
['missing signer', { ...verification, signerId: null }],
['invalid signer', { ...verification, signerId: 'lowercase' }],
['missing commit', { ...verification, sourceCommit: null }],
['invalid commit', { ...verification, sourceCommit: 'not-a-commit' }],
['unknown extra field', { ...verification, extra: true }],
])('fails closed for %s evidence', (_label, candidate) => {
expect(hasPersonaPrimaryControlAuthorization(candidate, expected)).toBe(false)
expect(hasPersonaPrimaryControlAuthorization(candidate)).toBe(false)
})
})

View file

@ -31,6 +31,14 @@ export type PersonaControlAuthorizationExpectation = {
observedAt?: number
}
export type NativePersonaControlAuthorizationVerification = {
status: 'VERIFIED'
reason: null
sourceCommit: string
signerId: string
authorizationEnabled: true
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
@ -39,50 +47,18 @@ function exactString(record: Record<string, unknown>, key: string, expected: str
return Reflect.get(record, key) === expected
}
/**
* Accepts only a native-verifier receipt bound to this exact planning request.
* It does not issue authority and treats absent or stale evidence as system-direct.
*/
/** Accepts only the bounded result emitted after native cryptographic verification. */
export function hasPersonaPrimaryControlAuthorization(
receipt: unknown,
expected: PersonaControlAuthorizationExpectation,
): receipt is PersonaControlAuthorizationReceipt {
if (!isRecord(receipt)) return false
if (!exactString(receipt, 'schema', PERSONA_CONTROL_AUTHORIZATION_SCHEMA)
|| !exactString(receipt, 'outcome', 'VERIFIED')
|| !exactString(receipt, 'verifier', 'GUANGHU_OS')
|| !exactString(receipt, 'signatureAlgorithm', 'Ed25519')
|| !exactString(receipt, 'scope', PERSONA_PRIMARY_LANGUAGE_PLANNING_SCOPE)
|| !exactString(receipt, 'personaId', expected.personaId)
|| !exactString(receipt, 'humanResponsibilitySubject', expected.humanResponsibilitySubject)
|| !exactString(receipt, 'repositoryHead', expected.repositoryHead)
|| !exactString(receipt, 'modelInstanceId', expected.modelInstanceId)
|| !exactString(receipt, 'requestId', expected.requestId)
|| !exactString(receipt, 'sourceLanguageAnchor', expected.sourceLanguageAnchor)) {
return false
}
const authorizationId = Reflect.get(receipt, 'authorizationId')
const evidenceDigest = Reflect.get(receipt, 'evidenceDigest')
const signerId = Reflect.get(receipt, 'signerId')
const signature = Reflect.get(receipt, 'signature')
const issuedAt = Reflect.get(receipt, 'issuedAt')
const validUntil = Reflect.get(receipt, 'validUntil')
if (typeof authorizationId !== 'string' || !authorizationId.trim()
|| typeof evidenceDigest !== 'string' || !/^[a-f0-9]{64}$/.test(evidenceDigest)
|| typeof signerId !== 'string' || !/^[A-Z0-9][A-Z0-9._:@-]{1,159}$/.test(signerId)
|| typeof signature !== 'string' || !/^[A-Za-z0-9_-]{80,128}$/.test(signature)
|| typeof issuedAt !== 'string'
|| typeof validUntil !== 'string') {
return false
}
const issuedAtMs = Date.parse(issuedAt)
const validUntilMs = Date.parse(validUntil)
const observedAt = expected.observedAt ?? Date.now()
return Number.isFinite(issuedAtMs)
&& Number.isFinite(validUntilMs)
&& issuedAtMs <= observedAt
&& observedAt <= validUntilMs
&& issuedAtMs < validUntilMs
verification: unknown,
): verification is NativePersonaControlAuthorizationVerification {
if (!isRecord(verification) || Object.keys(verification).length !== 5) return false
const sourceCommit = Reflect.get(verification, 'sourceCommit')
const signerId = Reflect.get(verification, 'signerId')
return exactString(verification, 'status', 'VERIFIED')
&& Reflect.get(verification, 'reason') === null
&& Reflect.get(verification, 'authorizationEnabled') === true
&& typeof sourceCommit === 'string'
&& /^[a-f0-9]{40}([a-f0-9]{24})?$/.test(sourceCommit)
&& typeof signerId === 'string'
&& /^[A-Z0-9][A-Z0-9._:@-]{1,159}$/.test(signerId)
}

View file

@ -1,4 +1,4 @@
import { describe, expect, it, vi } from 'vitest'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { AiModelProvider } from './aiTargets'
import type { LanguageGoalProjection } from './languageOperatingModel'
import type { PersonaLanguageGoalBinding } from './personaLanguageGoal'
@ -8,6 +8,11 @@ import type {
} from './personaRepositoryBinding'
import { planPersonaLanguageShellGoal } from './personaLanguageShellController'
const native = vi.hoisted(() => ({ invoke: vi.fn() }))
vi.mock('@tauri-apps/api/core', () => ({ invoke: native.invoke }))
vi.mock('../mock-tauri', () => ({ isTauri: () => false, mockInvoke: native.invoke }))
const provider: AiModelProvider = {
id: 'ollama-local',
name: 'Local Ollama',
@ -104,6 +109,8 @@ function input() {
}
describe('planPersonaLanguageShellGoal', () => {
beforeEach(() => native.invoke.mockReset())
it.each(['unavailable', 'unbound', 'ambiguous', 'error'] as const)(
'fails closed at repository phase %s before device identity or cognition',
async (phase) => {
@ -175,30 +182,24 @@ describe('planPersonaLanguageShellGoal', () => {
expect(planGoal).toHaveBeenCalledWith(expect.objectContaining({ personaAuthorized: false }))
})
it('enables persona-primary planning only for an exact request-bound authorization receipt', async () => {
it('enables persona-primary planning only after the native verifier accepts the exact receipt', async () => {
const planGoal = vi.fn().mockResolvedValue(plannedGoal)
const candidateReceipt = {
schema: 'hololake.persona-control-authorization/v2',
outcome: 'VERIFIED',
authorizationId: 'AUTH-001',
}
native.invoke.mockResolvedValue({
status: 'VERIFIED',
reason: null,
sourceCommit: 'c'.repeat(40),
signerId: 'GH-AIOS-AUTHORIZER-001',
authorizationEnabled: true,
})
await planPersonaLanguageShellGoal({
...input(),
loadPersonaControlAuthorization: vi.fn().mockResolvedValue({
schema: 'hololake.persona-control-authorization/v2',
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),
signerId: 'GH-AIOS-AUTHORIZER-001',
signatureAlgorithm: 'Ed25519',
signature: 'A'.repeat(86),
}),
personaControlAuthorizationReceipt: candidateReceipt,
authorizationObservedAt: Date.parse('2026-08-12T04:35:00+08:00'),
resolveRepository: vi.fn().mockResolvedValue(boundResolution()),
loadDeviceIdentity: vi.fn().mockResolvedValue({
@ -209,9 +210,68 @@ describe('planPersonaLanguageShellGoal', () => {
planGoal,
})
expect(native.invoke).toHaveBeenCalledWith(
'verify_persona_control_authorization',
{
receipt: candidateReceipt,
expectation: {
personaId: repositoryBinding.personaId,
humanResponsibilitySubject: repositoryBinding.humanResponsibilitySubject,
repositoryHead: repositoryBinding.gitHead,
modelInstanceId: 'MODEL-INSTANCE-001',
requestId: 'REQ-001',
sourceLanguageAnchor: 'current-human-utterance',
observedAtMilliseconds: Date.parse('2026-08-12T04:35:00+08:00'),
},
},
)
expect(planGoal).toHaveBeenCalledWith(expect.objectContaining({ personaAuthorized: true }))
})
it('keeps system-direct planning for a native denial', async () => {
const planGoal = vi.fn().mockResolvedValue(plannedGoal)
native.invoke.mockResolvedValue({
status: 'DENIED',
reason: 'NO_TRUSTED_SIGNER',
sourceCommit: 'c'.repeat(40),
signerId: null,
authorizationEnabled: false,
})
await planPersonaLanguageShellGoal({
...input(),
personaControlAuthorizationReceipt: { outcome: 'VERIFIED' },
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: false }))
})
it('keeps system-direct planning when the native verifier is unavailable', async () => {
const planGoal = vi.fn().mockResolvedValue(plannedGoal)
native.invoke.mockImplementationOnce(() => { throw new Error('SOURCE_UNAVAILABLE') })
await planPersonaLanguageShellGoal({
...input(),
personaControlAuthorizationReceipt: { outcome: 'VERIFIED' },
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: false }))
})
it('returns a stable binding error and never invokes cognition for invalid device evidence', async () => {
const planGoal = vi.fn()

View file

@ -35,14 +35,18 @@ export type PersonaLanguageShellPlan =
type RepositoryResolver = typeof resolvePersonaRepositoryBinding
type GoalPlanner = (input: PlanPersonaLanguageGoalInput) => Promise<LanguageGoalProjection>
type DeviceIdentityLoader = () => Promise<unknown>
type PersonaControlAuthorizationLoader = (input: {
personaId: string
humanResponsibilitySubject: string
repositoryHead: string
modelInstanceId: string
requestId: string
sourceLanguageAnchor: string
}) => Promise<unknown>
type PersonaControlAuthorizationVerificationInput = {
receipt: unknown
expectation: {
personaId: string
humanResponsibilitySubject: string
repositoryHead: string
modelInstanceId: string
requestId: string
sourceLanguageAnchor: string
observedAtMilliseconds: number
}
}
async function loadNativeDeviceIdentity(): Promise<unknown> {
return isTauri()
@ -50,8 +54,12 @@ async function loadNativeDeviceIdentity(): Promise<unknown> {
: mockInvoke<unknown>('guanghu_router_device_identity')
}
async function loadNoPersonaControlAuthorization(): Promise<null> {
return null
async function verifyNativePersonaControlAuthorization(
input: PersonaControlAuthorizationVerificationInput,
): Promise<unknown> {
return isTauri()
? invoke<unknown>('verify_persona_control_authorization', input)
: mockInvoke<unknown>('verify_persona_control_authorization', input)
}
function errorCode(error: unknown, fallback: string): string {
@ -79,6 +87,7 @@ export async function planPersonaLanguageShellGoal({
personaId,
repositoryPaths,
providers,
personaControlAuthorizationReceipt,
authorizationObservedAt,
detectedBoundaries,
requestId,
@ -87,13 +96,13 @@ export async function planPersonaLanguageShellGoal({
sourceLanguageAnchor,
resolveRepository = resolvePersonaRepositoryBinding,
loadDeviceIdentity = loadNativeDeviceIdentity,
loadPersonaControlAuthorization = loadNoPersonaControlAuthorization,
planGoal = planPersonaLanguageGoal,
}: {
utterance: string
personaId: string
repositoryPaths: readonly string[]
providers: readonly AiModelProvider[]
personaControlAuthorizationReceipt?: unknown
authorizationObservedAt?: number
detectedBoundaries?: RealityBoundary[]
requestId: string
@ -102,7 +111,6 @@ export async function planPersonaLanguageShellGoal({
sourceLanguageAnchor: string
resolveRepository?: RepositoryResolver
loadDeviceIdentity?: DeviceIdentityLoader
loadPersonaControlAuthorization?: PersonaControlAuthorizationLoader
planGoal?: GoalPlanner
}): Promise<PersonaLanguageShellPlan> {
const repository = await resolveRepository({ personaId, repositoryPaths })
@ -144,20 +152,22 @@ export async function planPersonaLanguageShellGoal({
requestId,
sourceLanguageAnchor,
}
let personaAuthorizationReceipt: unknown = null
try {
personaAuthorizationReceipt = await loadPersonaControlAuthorization(authorizationExpectation)
} catch {
// Authorization discovery is fail-closed but does not prevent safe,
// system-direct partner planning.
let nativeAuthorizationVerification: unknown = null
if (personaControlAuthorizationReceipt !== undefined) {
try {
nativeAuthorizationVerification = await verifyNativePersonaControlAuthorization({
receipt: personaControlAuthorizationReceipt,
expectation: {
...authorizationExpectation,
observedAtMilliseconds: authorizationObservedAt ?? Date.now(),
},
})
} catch {
// Native authorization verification is fail-closed but does not
// prevent safe, system-direct partner planning.
}
}
const personaAuthorized = hasPersonaPrimaryControlAuthorization(
personaAuthorizationReceipt,
{
...authorizationExpectation,
observedAt: authorizationObservedAt,
},
)
const personaAuthorized = hasPersonaPrimaryControlAuthorization(nativeAuthorizationVerification)
const goal = await planGoal({
utterance,
personaAuthorized,