Project live domain trust readiness
This commit is contained in:
parent
6b1bb203df
commit
7a90fad360
5 changed files with 120 additions and 4 deletions
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"schema": "gh-aios.hololake-local-stage-receipt/v1",
|
||||||
|
"receipt_id": "GH-HOLOLAKE-DOMAIN-TRUST-PROJECTION-20260810-001",
|
||||||
|
"result": "PASS_100_LOCAL_DOMAIN_TRUST_PROJECTION",
|
||||||
|
"development_id": "DEV-20260809-007",
|
||||||
|
"observed_at": "2026-08-10T05:00:28+08:00",
|
||||||
|
"source": {
|
||||||
|
"repository_id": "REPO-014",
|
||||||
|
"base_commit": "6b1bb203df952c588213cb87fe589c64a45c2075",
|
||||||
|
"branch": "main"
|
||||||
|
},
|
||||||
|
"online_trust_fact": {
|
||||||
|
"anchor_id": "GLW-PUBLIC-NAV-ANCHOR-001",
|
||||||
|
"anchor_version": "2026-08-09.4",
|
||||||
|
"repo_012_main": "34e1949a113be8d4871e61c094f2ae06e0bc5a45",
|
||||||
|
"registry_id": "GH-AIOS-TRUSTED-DOMAIN-MANIFEST-SIGNERS-001",
|
||||||
|
"registry_version": "1.0.0",
|
||||||
|
"registry_status": "CURRENT",
|
||||||
|
"signer_count": 0
|
||||||
|
},
|
||||||
|
"acceptance": {
|
||||||
|
"current_empty_signer_registry_is_visible": true,
|
||||||
|
"manifest_step_remains_blocked": true,
|
||||||
|
"session_capability_step_remains_blocked": true,
|
||||||
|
"online_receipt_step_remains_blocked": true,
|
||||||
|
"runtime_entry_button_disabled": true,
|
||||||
|
"raw_transport_errors_hidden": true
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"desktop_test_count": 51,
|
||||||
|
"desktop_test_failures": 0,
|
||||||
|
"production_build": "PASS",
|
||||||
|
"packaged_arm64_app": "PASS",
|
||||||
|
"codesign_deep_strict": "PASS",
|
||||||
|
"installed_binary_sha256": "6dda0936e6626142c41a7119d21b30ea8acd4b091ad9904bede68e35b096b07c",
|
||||||
|
"installed_app_asar_sha256": "42bc771f587d1705ea5a2954f4a997d7a245aaca0908db7c051a830e27e67071",
|
||||||
|
"current_ui_screenshot_sha256": "df0eaa5fc6c4c15b22b10d1ee102592cb0fc3c527b9c308739e97fffebb051e2"
|
||||||
|
},
|
||||||
|
"boundaries": [
|
||||||
|
"No target-domain signer is registered yet.",
|
||||||
|
"No live domain-runtime handoff endpoint is registered yet.",
|
||||||
|
"No domain session capability or matching online connection receipt was issued.",
|
||||||
|
"This receipt does not claim server deployment, runtime health, persona birth or notarization."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -43,8 +43,17 @@ interface ServerProfile {
|
||||||
|
|
||||||
interface DomainAccessStatus {
|
interface DomainAccessStatus {
|
||||||
blockers: string[];
|
blockers: string[];
|
||||||
|
domainId?: string;
|
||||||
|
nodeId?: string;
|
||||||
runtimeReady: boolean;
|
runtimeReady: boolean;
|
||||||
stage: 'checking' | 'login-required' | 'identity-verified' | 'runtime-ready';
|
stage: 'checking' | 'login-required' | 'identity-verified' | 'runtime-ready';
|
||||||
|
trustSource?: {
|
||||||
|
reason?: 'ANCHOR_INVALID' | 'REGISTRY_INVALID' | 'SOURCE_UNAVAILABLE';
|
||||||
|
registryVersion: string | null;
|
||||||
|
signerCount: number;
|
||||||
|
sourceCommit: string | null;
|
||||||
|
status: 'CURRENT' | 'DEGRADED_LAST_KNOWN_GOOD' | 'UNAVAILABLE';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function findFirstDocument(nodes: DocTreeNode[]): string | null {
|
function findFirstDocument(nodes: DocTreeNode[]): string | null {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Cloud, Laptop, ShieldCheck, X } from 'lucide-react';
|
import { Cloud, Laptop, ShieldCheck, X } from 'lucide-react';
|
||||||
import { projectDomainConnectionSteps, type DomainAccessProjection } from '../domain-connection';
|
import { projectDomainConnectionSteps, projectDomainTrustSource, type DomainAccessProjection } from '../domain-connection';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
access: DomainAccessProjection;
|
access: DomainAccessProjection;
|
||||||
|
|
@ -27,6 +27,7 @@ export function DomainConnectionSheet({ access, open, onClose, onEnterRuntime, o
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<p className="domain-connection-lead">进入域不是切换页面。系统必须验证账户、登记节点、目标域授权、会话能力和在线回执。</p>
|
<p className="domain-connection-lead">进入域不是切换页面。系统必须验证账户、登记节点、目标域授权、会话能力和在线回执。</p>
|
||||||
|
<p className="domain-connection-boundary">{projectDomainTrustSource(access)}</p>
|
||||||
|
|
||||||
<div className="domain-node-modes" aria-label="支持的节点类型">
|
<div className="domain-node-modes" aria-label="支持的节点类型">
|
||||||
<article><Laptop aria-hidden="true" /><span><strong>本地终端节点</strong><small>使用当前联网电脑承载本地工作;正式节点登记尚未开放。</small></span></article>
|
<article><Laptop aria-hidden="true" /><span><strong>本地终端节点</strong><small>使用当前联网电脑承载本地工作;正式节点登记尚未开放。</small></span></article>
|
||||||
|
|
@ -57,4 +58,3 @@ export function DomainConnectionSheet({ access, open, onClose, onEnterRuntime, o
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import test from 'node:test';
|
import test from 'node:test';
|
||||||
import { projectDomainConnectionSteps } from './domain-connection.js';
|
import { projectDomainConnectionSteps, projectDomainTrustSource } from './domain-connection.js';
|
||||||
|
|
||||||
test('code-channel account absence cannot be projected as a domain runtime login', () => {
|
test('code-channel account absence cannot be projected as a domain runtime login', () => {
|
||||||
const steps = projectDomainConnectionSteps({
|
const steps = projectDomainConnectionSteps({
|
||||||
|
|
@ -35,3 +35,37 @@ test('runtime-ready requires all four verified steps', () => {
|
||||||
assert.ok(steps.every(step => step.state === 'verified'));
|
assert.ok(steps.every(step => step.state === 'verified'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('a current empty signer registry is projected as a real manifest blocker', () => {
|
||||||
|
const access = {
|
||||||
|
blockers: ['verified_domain_manifest_missing'],
|
||||||
|
runtimeReady: false,
|
||||||
|
stage: 'identity-verified' as const,
|
||||||
|
trustSource: {
|
||||||
|
registryVersion: '1.0.0',
|
||||||
|
signerCount: 0,
|
||||||
|
sourceCommit: '34e1949a113be8d4871e61c094f2ae06e0bc5a45',
|
||||||
|
status: 'CURRENT' as const,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const manifest = projectDomainConnectionSteps(access)[1];
|
||||||
|
assert.equal(manifest.state, 'blocked');
|
||||||
|
assert.match(manifest.detail, /尚未登记任何目标域签名人/);
|
||||||
|
assert.match(projectDomainTrustSource(access), /当前.*v1\.0\.0.*34e1949a.*已登记签名人 0/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an unavailable trust source remains closed without leaking raw transport details', () => {
|
||||||
|
const access = {
|
||||||
|
blockers: ['verified_domain_manifest_missing'],
|
||||||
|
runtimeReady: false,
|
||||||
|
stage: 'identity-verified' as const,
|
||||||
|
trustSource: {
|
||||||
|
reason: 'SOURCE_UNAVAILABLE' as const,
|
||||||
|
registryVersion: null,
|
||||||
|
signerCount: 0,
|
||||||
|
sourceCommit: null,
|
||||||
|
status: 'UNAVAILABLE' as const,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
assert.match(projectDomainConnectionSteps(access)[1].detail, /系统保持关闭/);
|
||||||
|
assert.equal(projectDomainTrustSource(access), '可信清单来源不可用 · 域入口保持关闭');
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,17 @@ export type DomainAccessStage = 'checking' | 'login-required' | 'identity-verifi
|
||||||
|
|
||||||
export interface DomainAccessProjection {
|
export interface DomainAccessProjection {
|
||||||
blockers: string[];
|
blockers: string[];
|
||||||
|
domainId?: string;
|
||||||
|
nodeId?: string;
|
||||||
runtimeReady: boolean;
|
runtimeReady: boolean;
|
||||||
stage: DomainAccessStage;
|
stage: DomainAccessStage;
|
||||||
|
trustSource?: {
|
||||||
|
reason?: 'ANCHOR_INVALID' | 'REGISTRY_INVALID' | 'SOURCE_UNAVAILABLE';
|
||||||
|
registryVersion: string | null;
|
||||||
|
signerCount: number;
|
||||||
|
sourceCommit: string | null;
|
||||||
|
status: 'CURRENT' | 'DEGRADED_LAST_KNOWN_GOOD' | 'UNAVAILABLE';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DomainConnectionStep {
|
export interface DomainConnectionStep {
|
||||||
|
|
@ -51,12 +60,31 @@ export function projectDomainConnectionSteps(access: DomainAccessProjection): Do
|
||||||
return ordered.map(id => {
|
return ordered.map(id => {
|
||||||
const copy = stepCopy[id];
|
const copy = stepCopy[id];
|
||||||
const verified = access.runtimeReady || (!blockers.has(id) && access.stage !== 'checking');
|
const verified = access.runtimeReady || (!blockers.has(id) && access.stage !== 'checking');
|
||||||
|
let detail = verified ? copy.verified : copy.pending;
|
||||||
|
if (!verified && id === 'manifest' && access.trustSource) {
|
||||||
|
if (access.trustSource.status === 'UNAVAILABLE') {
|
||||||
|
detail = '当前无法回读灯塔的可信签名人登记表;系统保持关闭,不使用缓存猜测域权限';
|
||||||
|
} else if (access.trustSource.status === 'DEGRADED_LAST_KNOWN_GOOD') {
|
||||||
|
detail = '当前只能回读上一次可信签名人快照;实时来源恢复前不签发新的域权限';
|
||||||
|
} else if (access.trustSource.signerCount === 0) {
|
||||||
|
detail = '灯塔登记表已回读为当前版本,但尚未登记任何目标域签名人';
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
label: copy.label,
|
label: copy.label,
|
||||||
state: access.stage === 'checking' ? 'checking' : verified ? 'verified' : 'blocked',
|
state: access.stage === 'checking' ? 'checking' : verified ? 'verified' : 'blocked',
|
||||||
detail: access.stage === 'checking' ? '正在核对当前接入证据' : verified ? copy.verified : copy.pending,
|
detail: access.stage === 'checking' ? '正在核对当前接入证据' : detail,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function projectDomainTrustSource(access: DomainAccessProjection): string {
|
||||||
|
const source = access.trustSource;
|
||||||
|
if (!source) return '可信清单来源尚未由桌面运行时回读';
|
||||||
|
if (source.status === 'UNAVAILABLE') return '可信清单来源不可用 · 域入口保持关闭';
|
||||||
|
const commit = source.sourceCommit ? source.sourceCommit.slice(0, 8) : '未知提交';
|
||||||
|
const version = source.registryVersion ?? '未知版本';
|
||||||
|
const health = source.status === 'CURRENT' ? '当前' : '上次可信快照';
|
||||||
|
return `可信清单 ${health} · v${version} · ${commit} · 已登记签名人 ${source.signerCount}`;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue