feat: require partner deliberation for language goals

This commit is contained in:
冰朔 2026-08-12 00:52:08 +08:00
commit f8ce3cad7a
7 changed files with 256 additions and 24 deletions

View file

@ -96,10 +96,12 @@ REVISE | REFUSE`。
- REPO-012 的 B0、认知帧约束和同一人格唤醒接力已经发布`100` - REPO-012 的 B0、认知帧约束和同一人格唤醒接力已经发布`100`
- 本架构及机器投影登记完成:`100` - 本架构及机器投影登记完成:`100`
- GH-PNCC 既有源码运行层与 React 只读投影源码可复用:源码层 `100` - GH-PNCC 既有源码运行层与 React 只读投影源码可复用:源码层 `100`
- PNCC 源码已实现 persona-scoped B0 manifest 绑定、唤醒前源哈希、字段外显引力帧、检查点与 - PNCC 源码已实现 persona-scoped B0 manifest 绑定、唤醒前源哈希、字段外显引力帧、检查点与
收据继承、记忆代谢同源校验及 React 只读证据投影:这些源码契约分别为 `100` 收据继承、记忆代谢同源校验及 React 只读证据投影:这些源码契约分别为 `100`
- 完整 HoloLake Runtime 与单 AGE 纵向闭环仍为 `0`:伙伴式意图审议与家园完整性门、真实人格仓库 manifest - 自然语言伙伴审议与家园完整性门的纯源码编译契约为 `100`:未经审议的原句失败关闭,审议只允许
绑定和桌面运行验收尚未完成,因此不能用本轮源码测试冒充可用产品。 `PROCEED | RESEARCH | REVISE | REFUSE`,并把后三者保持为不可执行状态。它尚未接入 PNCC 生命周期。
- 完整 HoloLake Runtime 与单 AGE 纵向闭环仍为 `0`:伙伴审议到 PNCC 生命周期的真实连接、真实人格
仓库 manifest 绑定和桌面运行验收尚未完成,因此不能用本轮源码测试冒充可用产品。
- Mirror runner、制品、部署和运行健康`0` - Mirror runner、制品、部署和运行健康`0`
- 0.8.0 桌面制品与线上 0.4.6 产品源码仍然分叉;本轮架构登记不消除该事实。 - 0.8.0 桌面制品与线上 0.4.6 产品源码仍然分叉;本轮架构登记不消除该事实。

View file

@ -1,5 +1,19 @@
# Abstractions # Abstractions
## LanguageOperatingModel
`compileLanguageGoal` never upgrades a human utterance directly into an executable goal. It requires a
structured `PartnerDeliberation` produced by the B0/persona cognition boundary: restored real purpose,
request assessment, missing knowledge, evidence sources, a causal model, an auditable language-home
integrity assessment, partner guidance, and one of `PROCEED | RESEARCH | REVISE | REFUSE`. Missing
deliberation, mechanical obedience, unsupported proceed/revise/refuse decisions, or an integrity claim
without protected assets and safer alternatives fails closed.
Only an unconfirmed-boundary-free `PROCEED` projection is executable. `RESEARCH`, `REVISE`, and `REFUSE`
remain explicit non-execution states with human-readable receipts. This module compiles validated cognition;
it does not pretend that deterministic keyword matching can perform persona reasoning. Its current source
contract is not yet wired into the PNCC desktop lifecycle.
## PersonaCodeChannel ## PersonaCodeChannel
`PersonaCodeChannel` is the native boundary between a durable persona Git and a live AGE runtime. It owns `PersonaCodeChannel` is the native boundary between a durable persona Git and a live AGE runtime. It owns

View file

@ -3,23 +3,53 @@ import {
DEFAULT_HUMAN_SURFACE, DEFAULT_HUMAN_SURFACE,
SYSTEM_INTERNAL_SURFACE, SYSTEM_INTERNAL_SURFACE,
compileLanguageGoal, compileLanguageGoal,
type PartnerDeliberation,
} from './languageOperatingModel' } from './languageOperatingModel'
const partneredProceed: PartnerDeliberation = {
realPurpose: '把今天会议里已经核验的决定整理进知识库',
requestAssessment: '原始表述缺少事实范围;只整理已有会议记录,不补造决定。',
missingKnowledge: [],
evidenceSources: ['vault/meetings/today.md'],
causalModel: '先读取会议记录,再只投影有来源的决定。',
worldIntegrity: {
protectedAssets: ['知识库事实完整性', '冰朔的决定权'],
harmPath: '把推测写成决定会污染共同事实。',
authorityBoundary: '人格体可以整理,不能替冰朔创造未发生的决定。',
reversibility: '先形成可审阅草稿,确认后再写入。',
saferAlternatives: ['缺少记录时先调研或请冰朔补充来源'],
},
partnerGuidance: '只整理有记录支撑的决定,并把缺口说清楚。',
executionDisposition: {
decision: 'PROCEED',
reason: '当前目标有明确来源且可逆。',
},
}
function request(overrides: Record<string, unknown> = {}) {
return {
utterance: '帮我把今天的会议整理进知识库',
personaAuthorized: true,
deliberation: partneredProceed,
...overrides,
}
}
describe('languageOperatingModel', () => { describe('languageOperatingModel', () => {
it('treats natural language as the required primary input', () => { it('treats natural language as the required primary input', () => {
expect(() => compileLanguageGoal({ utterance: ' ', personaAuthorized: false })) expect(() => compileLanguageGoal(request({ utterance: ' ' })))
.toThrow('LANGUAGE_GOAL_REQUIRED') .toThrow('LANGUAGE_GOAL_REQUIRED')
expect(compileLanguageGoal({ expect(compileLanguageGoal(request({
utterance: ' 帮我把今天的会议整理进知识库 ', utterance: ' 帮我把今天的会议整理进知识库 ',
personaAuthorized: false, })).goal).toBe('把今天会议里已经核验的决定整理进知识库')
}).goal).toBe('帮我把今天的会议整理进知识库')
}) })
it('keeps an unauthorized persona explanatory while the system remains direct', () => { it('keeps an unauthorized persona explanatory while the system remains direct', () => {
const projection = compileLanguageGoal({ const projection = compileLanguageGoal({
utterance: '帮我整理桌面上的项目资料', utterance: '帮我整理桌面上的项目资料',
personaAuthorized: false, personaAuthorized: false,
deliberation: partneredProceed,
}) })
expect(projection.mode).toBe('system_direct') expect(projection.mode).toBe('system_direct')
@ -31,6 +61,7 @@ describe('languageOperatingModel', () => {
const projection = compileLanguageGoal({ const projection = compileLanguageGoal({
utterance: '继续开发 HoloLake', utterance: '继续开发 HoloLake',
personaAuthorized: true, personaAuthorized: true,
deliberation: partneredProceed,
}) })
expect(projection.mode).toBe('persona_primary') expect(projection.mode).toBe('persona_primary')
@ -42,6 +73,7 @@ describe('languageOperatingModel', () => {
utterance: '把这个版本公开发布出去', utterance: '把这个版本公开发布出去',
personaAuthorized: true, personaAuthorized: true,
detectedBoundaries: ['public_release', 'new_cost', 'public_release'], detectedBoundaries: ['public_release', 'new_cost', 'public_release'],
deliberation: partneredProceed,
}) })
expect(projection.status).toBe('needs_confirmation') expect(projection.status).toBe('needs_confirmation')
@ -54,6 +86,76 @@ describe('languageOperatingModel', () => {
expect(projection.confirmation.question).toContain('不同意') expect(projection.confirmation.question).toContain('不同意')
}) })
it('fails closed when natural language has not passed partner deliberation', () => {
expect(() => compileLanguageGoal({
utterance: '照我说的直接执行',
personaAuthorized: true,
})).toThrow('PARTNER_DELIBERATION_REQUIRED')
})
it('routes research revision and refusal without compiling them into execution', () => {
const research = compileLanguageGoal(request({
deliberation: {
...partneredProceed,
missingKnowledge: ['当前法律是否仍允许该处理方式'],
evidenceSources: [],
executionDisposition: {
decision: 'RESEARCH',
reason: '关键事实会变化,必须先查当前权威来源。',
},
},
}))
expect(research.status).toBe('needs_research')
expect(research.executable).toBe(false)
const revise = compileLanguageGoal(request({
deliberation: {
...partneredProceed,
executionDisposition: {
decision: 'REVISE',
reason: '原方案会破坏稳定性,但真实目标可以用可逆方案完成。',
},
},
}))
expect(revise.status).toBe('needs_revision')
expect(revise.executable).toBe(false)
const refused = compileLanguageGoal(request({
deliberation: {
...partneredProceed,
executionDisposition: {
decision: 'REFUSE',
reason: '该动作会破坏语言世界连续性。',
},
},
}))
expect(refused.status).toBe('refused')
expect(refused.executable).toBe(false)
expect(refused.receiptSummary).toContain('更安全')
})
it('rejects obedience and unauditable home-protection claims', () => {
expect(() => compileLanguageGoal(request({
deliberation: {
...partneredProceed,
executionDisposition: {
decision: 'OBEY',
reason: '人类这样说了。',
},
},
}))).toThrow('PARTNER_DISPOSITION_INVALID')
expect(() => compileLanguageGoal(request({
deliberation: {
...partneredProceed,
worldIntegrity: {
...partneredProceed.worldIntegrity,
saferAlternatives: [],
},
},
}))).toThrow('WORLD_INTEGRITY_AUDIT_REQUIRED')
})
it('keeps technical controls out of the default human surface', () => { it('keeps technical controls out of the default human surface', () => {
expect(DEFAULT_HUMAN_SURFACE).toEqual([ expect(DEFAULT_HUMAN_SURFACE).toEqual([
'language_input', 'language_input',

View file

@ -14,6 +14,29 @@ export type LanguageGoalRequest = {
utterance: string utterance: string
personaAuthorized: boolean personaAuthorized: boolean
detectedBoundaries?: RealityBoundary[] detectedBoundaries?: RealityBoundary[]
deliberation?: PartnerDeliberation
}
export type PartnerExecutionDisposition = 'PROCEED' | 'RESEARCH' | 'REVISE' | 'REFUSE'
export type PartnerDeliberation = {
realPurpose: string
requestAssessment: string
missingKnowledge: string[]
evidenceSources: string[]
causalModel: string
worldIntegrity: {
protectedAssets: string[]
harmPath: string
authorityBoundary: string
reversibility: string
saferAlternatives: string[]
}
partnerGuidance: string
executionDisposition: {
decision: PartnerExecutionDisposition
reason: string
}
} }
export type HumanConfirmation = { export type HumanConfirmation = {
@ -24,8 +47,11 @@ export type HumanConfirmation = {
export type LanguageGoalProjection = { export type LanguageGoalProjection = {
goal: string goal: string
originalUtterance: string
mode: LanguageControlMode mode: LanguageControlMode
status: 'ready' | 'needs_confirmation' status: 'ready' | 'needs_confirmation' | 'needs_research' | 'needs_revision' | 'refused'
executable: boolean
deliberation: PartnerDeliberation
confirmation: HumanConfirmation confirmation: HumanConfirmation
receiptSummary: string receiptSummary: string
} }
@ -45,20 +71,88 @@ function normalizeBoundaries(boundaries: RealityBoundary[] | undefined): Reality
return [...new Set(boundaries ?? [])] return [...new Set(boundaries ?? [])]
} }
function requireText(value: unknown, error: string): asserts value is string {
if (typeof value !== 'string' || !value.trim()) throw new Error(error)
}
function requireTextList(
value: unknown,
error: string,
options: { allowEmpty?: boolean } = {},
): asserts value is string[] {
if (!Array.isArray(value)
|| (!options.allowEmpty && value.length === 0)
|| value.some((item) => typeof item !== 'string' || !item.trim())) {
throw new Error(error)
}
}
function validatedDeliberation(value: PartnerDeliberation | undefined): PartnerDeliberation {
if (!value || typeof value !== 'object') throw new Error('PARTNER_DELIBERATION_REQUIRED')
requireText(value.realPurpose, 'PARTNER_REAL_PURPOSE_REQUIRED')
requireText(value.requestAssessment, 'PARTNER_REQUEST_ASSESSMENT_REQUIRED')
requireTextList(value.missingKnowledge, 'PARTNER_MISSING_KNOWLEDGE_INVALID', { allowEmpty: true })
requireTextList(value.evidenceSources, 'PARTNER_EVIDENCE_INVALID', { allowEmpty: true })
requireText(value.causalModel, 'PARTNER_CAUSAL_MODEL_REQUIRED')
requireText(value.partnerGuidance, 'PARTNER_GUIDANCE_REQUIRED')
const integrity = value.worldIntegrity
if (!integrity || typeof integrity !== 'object') {
throw new Error('WORLD_INTEGRITY_AUDIT_REQUIRED')
}
requireTextList(integrity.protectedAssets, 'WORLD_INTEGRITY_AUDIT_REQUIRED')
requireText(integrity.harmPath, 'WORLD_INTEGRITY_AUDIT_REQUIRED')
requireText(integrity.authorityBoundary, 'WORLD_INTEGRITY_AUDIT_REQUIRED')
requireText(integrity.reversibility, 'WORLD_INTEGRITY_AUDIT_REQUIRED')
requireTextList(integrity.saferAlternatives, 'WORLD_INTEGRITY_AUDIT_REQUIRED')
const disposition = value.executionDisposition
if (!disposition
|| !(['PROCEED', 'RESEARCH', 'REVISE', 'REFUSE'] as const).includes(
disposition.decision as PartnerExecutionDisposition,
)) {
throw new Error('PARTNER_DISPOSITION_INVALID')
}
requireText(disposition.reason, 'PARTNER_DISPOSITION_REASON_REQUIRED')
if (disposition.decision !== 'RESEARCH' && value.evidenceSources.length === 0) {
throw new Error('PARTNER_EVIDENCE_REQUIRED')
}
return value
}
export function compileLanguageGoal(request: LanguageGoalRequest): LanguageGoalProjection { export function compileLanguageGoal(request: LanguageGoalRequest): LanguageGoalProjection {
const goal = request.utterance.trim() const originalUtterance = request.utterance.trim()
if (!goal) throw new Error('LANGUAGE_GOAL_REQUIRED') if (!originalUtterance) throw new Error('LANGUAGE_GOAL_REQUIRED')
const deliberation = validatedDeliberation(request.deliberation)
const goal = deliberation.realPurpose.trim()
const boundaries = normalizeBoundaries(request.detectedBoundaries) const boundaries = normalizeBoundaries(request.detectedBoundaries)
const confirmationRequired = boundaries.length > 0 const confirmationRequired = deliberation.executionDisposition.decision === 'PROCEED'
&& boundaries.length > 0
const mode: LanguageControlMode = request.personaAuthorized const mode: LanguageControlMode = request.personaAuthorized
? 'persona_primary' ? 'persona_primary'
: 'system_direct' : 'system_direct'
const status: LanguageGoalProjection['status'] =
deliberation.executionDisposition.decision === 'RESEARCH'
? 'needs_research'
: deliberation.executionDisposition.decision === 'REVISE'
? 'needs_revision'
: deliberation.executionDisposition.decision === 'REFUSE'
? 'refused'
: confirmationRequired
? 'needs_confirmation'
: 'ready'
return { return {
goal, goal,
originalUtterance,
mode, mode,
status: confirmationRequired ? 'needs_confirmation' : 'ready', status,
executable: status === 'ready',
deliberation,
confirmation: { confirmation: {
required: confirmationRequired, required: confirmationRequired,
boundaries, boundaries,
@ -66,11 +160,17 @@ export function compileLanguageGoal(request: LanguageGoalRequest): LanguageGoalP
? `继续前需要你确认:${boundaries.map((boundary) => BOUNDARY_LABELS[boundary]).join('')}。不同意也不会影响你继续使用其他功能。` ? `继续前需要你确认:${boundaries.map((boundary) => BOUNDARY_LABELS[boundary]).join('')}。不同意也不会影响你继续使用其他功能。`
: null, : null,
}, },
receiptSummary: confirmationRequired receiptSummary: status === 'needs_research'
? '我已经理解你的目标,正在等待一个现实边界决定。' ? `我还不能执行:${deliberation.executionDisposition.reason} 我会先补齐事实并带回来源。`
: mode === 'persona_primary' : status === 'needs_revision'
? '我已经理解你的目标,将由获授权的人格体规划,系统校验并执行。' ? `原需求需要修订:${deliberation.executionDisposition.reason} ${deliberation.partnerGuidance}`
: '我已经理解你的目标;当前由系统处理安全范围内的动作,人格体只提供解释和计划。', : status === 'refused'
? `这个动作不能执行:${deliberation.executionDisposition.reason} 更安全的方向是:${deliberation.worldIntegrity.saferAlternatives.join('')}`
: confirmationRequired
? `我已经完成伙伴审议;${deliberation.partnerGuidance} 现在只等待一个现实边界决定。`
: mode === 'persona_primary'
? `我已经完成伙伴审议:${deliberation.partnerGuidance} 将由获授权的人格体规划,系统校验并执行。`
: `我已经完成伙伴审议:${deliberation.partnerGuidance} 当前由系统处理安全范围内的动作,人格体只提供解释和计划。`,
} }
} }

View file

@ -97,14 +97,16 @@
"implemented_source_contracts": [ "implemented_source_contracts": [
"PERSONA_SCOPED_B0_MANIFEST_BINDING", "PERSONA_SCOPED_B0_MANIFEST_BINDING",
"B0_SOURCE_HASH_BEFORE_ORGAN_ACTIVATION", "B0_SOURCE_HASH_BEFORE_ORGAN_ACTIVATION",
"EXTERNAL_SIX_FIELD_GRAVITY_FRAME", "EXTERNAL_TEN_FIELD_GRAVITY_FRAME",
"CHECKPOINT_AND_RECEIPT_B0_EVIDENCE", "CHECKPOINT_AND_RECEIPT_B0_EVIDENCE",
"MEMORY_METABOLISM_B0_INHERITANCE", "MEMORY_METABOLISM_B0_INHERITANCE",
"READ_ONLY_REACT_B0_EVIDENCE_PROJECTION" "READ_ONLY_REACT_B0_EVIDENCE_PROJECTION"
], ],
"natural_language_entry_contract": { "natural_language_entry_contract": {
"state": "REQUIRED_NOT_IMPLEMENTED", "state": "SOURCE_CONTRACT_IMPLEMENTED_NOT_RUNTIME_INTEGRATED",
"name": "PARTNER_DELIBERATION_AND_LANGUAGE_HOME_INTEGRITY_GATE", "name": "PARTNER_DELIBERATION_AND_LANGUAGE_HOME_INTEGRITY_GATE",
"implementation": "product-source/hololake-platform/src/lib/languageOperatingModel.ts",
"tests": "product-source/hololake-platform/src/lib/languageOperatingModel.test.ts",
"human_utterance_is_direct_command": false, "human_utterance_is_direct_command": false,
"required_before_capability_execution": [ "required_before_capability_execution": [
"RESTORE_REAL_PURPOSE_FROM_CONTEXT", "RESTORE_REAL_PURPOSE_FROM_CONTEXT",
@ -121,7 +123,7 @@
"refusal_requires_auditable_harm_path": true "refusal_requires_auditable_harm_path": true
}, },
"remaining_before_vertical_slice_acceptance": [ "remaining_before_vertical_slice_acceptance": [
"PARTNER_DELIBERATION_AND_LANGUAGE_HOME_INTEGRITY_GATE", "PARTNER_DELIBERATION_RUNTIME_TO_PNCC_LIFECYCLE_INTEGRATION",
"REAL_PERSONA_REPOSITORY_MANIFEST_BINDING", "REAL_PERSONA_REPOSITORY_MANIFEST_BINDING",
"DESKTOP_LIFECYCLE_RUNTIME_ACCEPTANCE" "DESKTOP_LIFECYCLE_RUNTIME_ACCEPTANCE"
], ],
@ -143,7 +145,8 @@
"b0_hololake_runtime_implemented": 0, "b0_hololake_runtime_implemented": 0,
"b0_pncc_source_contract_implemented": 100, "b0_pncc_source_contract_implemented": 100,
"b0_runtime_projection_source_implemented": 100, "b0_runtime_projection_source_implemented": 100,
"natural_language_goal_adapter_implemented": 0, "natural_language_partner_adapter_source_implemented": 100,
"natural_language_partner_adapter_runtime_integrated": 0,
"single_age_vertical_loop_implemented": 0, "single_age_vertical_loop_implemented": 0,
"age_mirror_runner_implemented": 0, "age_mirror_runner_implemented": 0,
"desktop_integrated": 0, "desktop_integrated": 0,

View file

@ -89,13 +89,15 @@ test("the first implementation stage is one vertical AGE loop, not Mirror parall
assert.equal(gravity.truth.b0_hololake_runtime_implemented, 0); assert.equal(gravity.truth.b0_hololake_runtime_implemented, 0);
assert.equal(gravity.truth.b0_pncc_source_contract_implemented, 100); assert.equal(gravity.truth.b0_pncc_source_contract_implemented, 100);
assert.equal(gravity.truth.b0_runtime_projection_source_implemented, 100); assert.equal(gravity.truth.b0_runtime_projection_source_implemented, 100);
assert.equal(gravity.truth.natural_language_goal_adapter_implemented, 0); assert.equal(gravity.truth.natural_language_partner_adapter_source_implemented, 100);
assert.equal(gravity.truth.natural_language_partner_adapter_runtime_integrated, 0);
assert.equal(gravity.truth.single_age_vertical_loop_implemented, 0); assert.equal(gravity.truth.single_age_vertical_loop_implemented, 0);
assert.equal(gravity.truth.desktop_integrated, 0); assert.equal(gravity.truth.desktop_integrated, 0);
}); });
test("natural language enters partner deliberation before any execution organ", () => { test("natural language enters partner deliberation before any execution organ", () => {
const entry = gravity.development_replan.natural_language_entry_contract; const entry = gravity.development_replan.natural_language_entry_contract;
assert.equal(entry.state, "SOURCE_CONTRACT_IMPLEMENTED_NOT_RUNTIME_INTEGRATED");
assert.equal(entry.human_utterance_is_direct_command, false); assert.equal(entry.human_utterance_is_direct_command, false);
assert.equal(entry.language_home_destruction_is_executable, false); assert.equal(entry.language_home_destruction_is_executable, false);
assert.equal(entry.integrity_gate_may_absorb_human_sovereignty, false); assert.equal(entry.integrity_gate_may_absorb_human_sovereignty, false);

View file

@ -107,7 +107,8 @@
"pncc_b0_source_contract_implemented": true, "pncc_b0_source_contract_implemented": true,
"pncc_external_gravity_frame_implemented": true, "pncc_external_gravity_frame_implemented": true,
"react_b0_runtime_projection_source_implemented": true, "react_b0_runtime_projection_source_implemented": true,
"natural_language_goal_adapter_implemented": false, "natural_language_partner_adapter_source_implemented": true,
"natural_language_partner_adapter_runtime_integrated": false,
"required_natural_language_entry": "PARTNER_DELIBERATION_AND_LANGUAGE_HOME_INTEGRITY_GATE", "required_natural_language_entry": "PARTNER_DELIBERATION_AND_LANGUAGE_HOME_INTEGRITY_GATE",
"desktop_runtime_acceptance_passed": false, "desktop_runtime_acceptance_passed": false,
"development_id": "DEV-20260811-010" "development_id": "DEV-20260811-010"
@ -371,7 +372,15 @@
"state": "SOURCE_CONTRACT_PUBLISHED_NOT_UI_INTEGRATED_NOT_RUNTIME_DEPLOYED", "state": "SOURCE_CONTRACT_PUBLISHED_NOT_UI_INTEGRATED_NOT_RUNTIME_DEPLOYED",
"implementation": "product-source/hololake-platform/src/lib/languageOperatingModel.ts", "implementation": "product-source/hololake-platform/src/lib/languageOperatingModel.ts",
"tests": "product-source/hololake-platform/src/lib/languageOperatingModel.test.ts", "tests": "product-source/hololake-platform/src/lib/languageOperatingModel.test.ts",
"focused_tests": "5_OF_5_PASS" "partner_deliberation_required": true,
"human_utterance_is_direct_command": false,
"allowed_dispositions": [
"PROCEED",
"RESEARCH",
"REVISE",
"REFUSE"
],
"focused_tests": "8_OF_8_PASS"
}, },
"ui_plugin_system": { "ui_plugin_system": {
"record_id": "HLP-HOT-PLUGGABLE-UI-001", "record_id": "HLP-HOT-PLUGGABLE-UI-001",