feat: surface Guanghu era time authority

This commit is contained in:
冰朔 2026-08-17 14:06:45 +08:00
commit 3294447dce
8 changed files with 733 additions and 23 deletions

View file

@ -63,6 +63,7 @@ interface HomeStatus {
mcpRole: string
}
interface PersonalChannelIdentity { humanSubjectId: string; displayName: string; channelId: string; createdAtUnixMs: number }
interface PersonalChannelModule { moduleId: string; kind: string; displayName: string; state: string; installedAtUnixMs: number; timeZone: string; calendarName: string; clockVerification: string }
interface LoginSession { username: string; host: string; domain: string; signedInAtUnixMs: number }
interface LoginReceipt { username: string; email: string; host: string; domain: string }
interface UserPnccChannelSnapshot {
@ -86,7 +87,11 @@ interface UserPnccChannelSnapshot {
authority: string
}
interface PersonalChannelEvent { sequence: number; eventId: string; kind: string; summary: string; occurredAtUnixMs: number; receiptId: string; receiptHash: string }
interface PersonalChannelSnapshot { state: string; identity?: PersonalChannelIdentity; recentEvents: PersonalChannelEvent[]; integrity: { state: string; eventCount: number; receiptCount: number } }
interface PersonalChannelSnapshot { state: string; identity?: PersonalChannelIdentity; recentEvents: PersonalChannelEvent[]; modules: PersonalChannelModule[]; integrity: { state: string; eventCount: number; receiptCount: number } }
interface BeijingTimeCoordinate { unixMs: number; beijingTime: string; timeZone: string; clockSource: string; clockVerification: string; networkSyncState: string; networkSynchronizedAtUnixMs?: number; networkUncertaintyMs?: number; continuesWhileHololakeIsClosed: boolean; guanghuEpochDate: string; guanghuEraDay: number; historicalEpochPrecision: string }
interface PersonaTimeAuthorityStartup { state: string; synchronizationAttempted: boolean; networkTimeUrl: string; coordinate: BeijingTimeCoordinate }
interface GuanghuEraEvent { eventId: string; displayDate: string; datePrecision: string; title: string; summary: string; evidenceState: string; sourceRecord: string }
interface GuanghuEraTimeline { state: string; eraName: string; calendarName: string; epochDate: string; epochPrecision: string; publicRealityBoundary: string; currentCoordinate: BeijingTimeCoordinate; events: GuanghuEraEvent[] }
interface KnowledgeDocumentSummary {
source: KnowledgeSource
path: string
@ -262,7 +267,7 @@ interface EnterpriseReceiptEnvelope {
}
const previewStatus: HomeStatus = { directLocalBrokerState: 'UNVERIFIED', directConnectionCount: 0, resumableSessionCount: 0, codeRepositoryMountCount: 0, pnccReceiptCount: 0, updateState: 'READY_HUMAN_CONFIRMATION_REQUIRED', releaseRecoveryState: 'NONE', mcpRole: 'DISCOVERY_RECOVERY_COMPATIBILITY_ONLY' }
const previewPersonal: PersonalChannelSnapshot = { state: 'UNAVAILABLE', recentEvents: [], integrity: { state: 'UNKNOWN', eventCount: 0, receiptCount: 0 } }
const previewPersonal: PersonalChannelSnapshot = { state: 'UNAVAILABLE', recentEvents: [], modules: [], integrity: { state: 'UNKNOWN', eventCount: 0, receiptCount: 0 } }
const previewKnowledge: KnowledgeSnapshot = { state: 'UNAVAILABLE', nativeRoot: '', legacyAvailable: false, documents: [], rawDocumentCount: 0, uniqueDocumentCount: 0, duplicateDocumentCount: 0, truncated: false }
const previewCode: CodeChannelSnapshot = { state: 'UNAVAILABLE', channels: [], authority: 'LOCAL_SOURCE_ACCESS_ONLY_NO_PUSH_OR_DEPLOY_AUTHORITY' }
const themes: Array<{ id: ThemeId; name: string }> = [
@ -320,6 +325,36 @@ function LakePool({ className, title, meta, open = false, risen = false, onClick
</button>
}
function displayBeijingTime(coordinate: BeijingTimeCoordinate | null): string {
if (!coordinate) return '正在读取北京时间'
return coordinate.beijingTime.replace('T', ' ').slice(0, 23)
}
function EraHomeEntry({ timeline, coordinate, onOpen }: { timeline: GuanghuEraTimeline | null; coordinate: BeijingTimeCoordinate | null; onOpen: () => void }) {
const markers = timeline ? [timeline.events[0], timeline.events[3], timeline.events[6], timeline.events[timeline.events.length - 1]].filter(Boolean) : []
return <button className="era-home-entry" type="button" onClick={onOpen} aria-label="展开曜冥纪元演化时间线">
<span className="era-home-heading"><b></b><small>{coordinate ? `光湖历第 ${coordinate.guanghuEraDay}` : '从 2025-04-26 起'}</small></span>
<span className="era-home-markers" aria-hidden="true">{markers.map((event) => <i key={event.eventId}><em/>{event.displayDate.slice(0, 7)}</i>)}</span>
<span className="era-home-now">{displayBeijingTime(coordinate)} · </span>
</button>
}
function EraTimelineOverlay({ timeline, coordinate, onClose }: { timeline: GuanghuEraTimeline; coordinate: BeijingTimeCoordinate | null; onClose: () => void }) {
const activeCoordinate = coordinate ?? timeline.currentCoordinate
const networkSynchronized = activeCoordinate.networkSyncState === 'SYNCHRONIZED_ON_APPLICATION_OPEN'
return <div className="era-overlay" role="dialog" aria-modal="true" aria-label="曜冥纪元演化史">
<button className="era-overlay-scrim" type="button" aria-label="关闭曜冥纪元" onClick={onClose}/>
<section className="era-timeline-panel">
<header><div><span>YAOMING ERA · HOLOLAKE CALENDAR</span><h2>{timeline.eraName}</h2><p>{timeline.calendarName} {activeCoordinate.guanghuEraDay} · {displayBeijingTime(activeCoordinate)}</p></div><button type="button" aria-label="关闭" onClick={onClose}>×</button></header>
<p className="era-clock-boundary">{networkSynchronized ? `HoloLake 打开时已通过加密网络读取现实时间锚点${activeCoordinate.networkUncertaintyMs ? `,当前估计误差不超过约 ${activeCoordinate.networkUncertaintyMs} 毫秒` : ''}` : '联网校时尚未完成,当前暂用本机现实系统时钟并明确标记等待同步。'} HoloLake </p>
<ol>{timeline.events.map((event) => <li key={event.eventId}>
<time>{event.displayDate}</time><i aria-hidden="true"/><div><h3>{event.title}</h3><p>{event.summary}</p></div>
</li>)}</ol>
<footer> 2025-04-26 线</footer>
</section>
</div>
}
function getOrCreateLocalId(key: string, prefix: string) {
const existing = window.localStorage.getItem(key)
if (existing) return existing
@ -448,6 +483,15 @@ function HoloLakeApp() {
const [toolReturnStage, setToolReturnStage] = useState<WorldStage>('channel')
const [status, setStatus] = useState<HomeStatus>(previewStatus)
const [personal, setPersonal] = useState<PersonalChannelSnapshot>(previewPersonal)
const [eraTimeline, setEraTimeline] = useState<GuanghuEraTimeline | null>(null)
const [beijingCoordinate, setBeijingCoordinate] = useState<BeijingTimeCoordinate | null>(null)
const [eraOpen, setEraOpen] = useState(false)
const openEraTimeline = useCallback(() => {
setEraOpen(true)
invoke<PersonaTimeAuthorityStartup>('start_persona_time_authority')
.then((startup) => setBeijingCoordinate(startup.coordinate))
.catch(() => undefined)
}, [])
const [knowledge, setKnowledge] = useState<KnowledgeSnapshot>(previewKnowledge)
const [codeChannels, setCodeChannels] = useState<CodeChannelSnapshot>(previewCode)
const [activeDocument, setActiveDocument] = useState<KnowledgeDocument | null>(null)
@ -552,16 +596,25 @@ function HoloLakeApp() {
}, [])
const refreshCore = useCallback(async () => {
const [homeResult, personalResult, knowledgeResult, codeResult] = await Promise.allSettled([
try {
const startup = await invoke<PersonaTimeAuthorityStartup>('start_persona_time_authority')
setBeijingCoordinate(startup.coordinate)
} catch { /* 联网失败时其余首页能力仍可启动。 */ }
const [homeResult, personalResult, knowledgeResult, codeResult, eraResult] = await Promise.allSettled([
invoke<HomeStatus>('get_hololake_home_status'),
invoke<PersonalChannelSnapshot>('get_personal_channel_snapshot'),
invoke<KnowledgeSnapshot>('get_knowledge_snapshot'),
invoke<CodeChannelSnapshot>('get_code_channel_snapshot'),
invoke<GuanghuEraTimeline>('get_guanghu_era_timeline'),
])
if (homeResult.status === 'fulfilled') setStatus(homeResult.value)
if (personalResult.status === 'fulfilled') setPersonal(personalResult.value)
if (knowledgeResult.status === 'fulfilled') setKnowledge(knowledgeResult.value)
if (codeResult.status === 'fulfilled') setCodeChannels(codeResult.value)
if (eraResult.status === 'fulfilled') {
setEraTimeline(eraResult.value)
setBeijingCoordinate(eraResult.value.currentCoordinate)
}
}, [])
const loadReceipts = useCallback(async () => {
try {
@ -575,6 +628,12 @@ function HoloLakeApp() {
window.addEventListener('focus', refreshWhenHumanReturns)
return () => window.removeEventListener('focus', refreshWhenHumanReturns)
}, [refreshCore])
useEffect(() => {
if (!eraOpen) return
const closeOnEscape = (event: KeyboardEvent) => { if (event.key === 'Escape') setEraOpen(false) }
window.addEventListener('keydown', closeOnEscape)
return () => window.removeEventListener('keydown', closeOnEscape)
}, [eraOpen])
useEffect(() => {
invoke<NearbyAiDiscoverySnapshot>('get_nearby_ai_discovery')
.then(setNearbyDiscovery)
@ -734,6 +793,7 @@ function HoloLakeApp() {
: status.resumableSessionCount > 0
? '原生会话可续接 · 当前离线'
: '原生接口已驻留 · 尚无客户端'
const timeAuthorityModule = personal.modules.find((module) => module.kind === 'PERSONA_TIME_AUTHORITY')
const openDocument = async (source: KnowledgeSource, path: string) => {
setKnowledgeBusy(true)
@ -1124,6 +1184,12 @@ function HoloLakeApp() {
<button className="metric-panel" type="button" onClick={() => setView('code')}><span></span><strong>{codeChannels.channels.length}</strong><small></small></button>
<button className="metric-panel" type="button" onClick={() => setView('receipts')}><span></span><strong>{personal.integrity.receiptCount + status.pnccReceiptCount}</strong><small></small></button>
</div>
{timeAuthorityModule && <button className="time-module-strip" type="button" onClick={openEraTimeline}>
<span><i/><b>{timeAuthorityModule.displayName}</b><small> · {timeAuthorityModule.calendarName}</small></span>
<strong>{beijingCoordinate ? `${beijingCoordinate.guanghuEraDay}` : '时间正在流动'}</strong>
<time>{displayBeijingTime(beijingCoordinate)}</time>
<em>{beijingCoordinate?.networkSyncState === 'SYNCHRONIZED_ON_APPLICATION_OPEN' ? '打开软件时已联网校时' : '本机现实时间 · 等待联网校时'}</em>
</button>}
<div className="overview-columns">
<section className="plain-panel recent-panel">
<header><div><h2></h2><p></p></div><button type="button" onClick={() => setView('knowledge')}></button></header>
@ -1362,8 +1428,10 @@ function HoloLakeApp() {
<button className="gate-back" type="button" onClick={() => { setGateStage('number'); setGateMessage(''); setLoginMessage('') }}></button>
</section>
</>}
{gateStage === 'number' && !gateOpen && !activeDomainInfo && <EraHomeEntry timeline={eraTimeline} coordinate={beijingCoordinate} onOpen={openEraTimeline}/>}
</main>
<footer className="world-footer"><b> · </b><span>GH-AIOS</span></footer>
{eraOpen && eraTimeline && <EraTimelineOverlay timeline={eraTimeline} coordinate={beijingCoordinate} onClose={() => setEraOpen(false)}/>}
</div>
}
@ -1377,6 +1445,7 @@ function HoloLakeApp() {
<div className="broadcast-stream"><p><i/> · 线</p><p><i/> · {enterpriseEntry?.registry_version || 'HLDP v1.0'}</p>{repoLogin.domain !== 'FIFTH_DOMAIN' && <p><i/> · {domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)}</p>}<p><i/>HoloLake · V0.4.1</p></div>
<LakePool className="home-primary" title={repoLogin.domain === 'FIFTH_DOMAIN' ? '永恒湖心系统' : '光湖频道'} meta={repoLogin.domain === 'FIFTH_DOMAIN' ? '进入私人系统' : `${domainDisplayName(enterpriseEntry?.subject.domain || repoLogin.domain)} · 责任工作入口`} open onClick={() => setWorldStage(repoLogin.domain === 'FIFTH_DOMAIN' ? (isZhizhi ? 'heart' : 'channel') : 'channel')}/>
<LakePool className="home-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
<EraHomeEntry timeline={eraTimeline} coordinate={beijingCoordinate} onOpen={openEraTimeline}/>
</section>}
{worldStage === 'heart' && isZhizhi && <section className="channel-world private-route-world">
<button className="world-back" type="button" onClick={() => setWorldStage('domain')}> 退</button>
@ -1396,6 +1465,7 @@ function HoloLakeApp() {
<LakePool className="channel-knowledge" title="知识空间" meta={`${knowledge.uniqueDocumentCount} 唯一页`} onClick={() => openWorldTool('knowledge')}/>
<LakePool className="channel-code" title="内置代码频道" meta={userPncc?.state === 'READY' ? '明天见 · Git 已就绪' : '正在建立'} onClick={() => openWorldTool('code')}/>
<LakePool className="channel-light" title="奶瓶频道" meta="前往陪伴宝宝人格体" onClick={() => setWorldStage('bottle')}/>
{timeAuthorityModule && <LakePool className="channel-time" title="时间主控" meta={beijingCoordinate ? `光湖历第 ${beijingCoordinate.guanghuEraDay}` : '北京时间正在流动'} onClick={openEraTimeline}/>}
<LakePool className="channel-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
</section>}
{worldStage === 'bottle' && repoLogin.domain === 'FIFTH_DOMAIN' && <section className="channel-world bottle-world">
@ -1448,6 +1518,7 @@ function HoloLakeApp() {
<div className="world-location"><h1></h1><p> · ICE-GL · </p></div>
<LakePool className="channel-main" title="频道全景" meta="心跳核心频道" open onClick={() => openWorldTool('overview')}/>
<LakePool className="channel-knowledge" title="知识空间" meta={`${knowledge.uniqueDocumentCount} 唯一页`} onClick={() => openWorldTool('knowledge')}/>
{timeAuthorityModule && <LakePool className="channel-time" title="时间主控" meta={beijingCoordinate ? `光湖历第 ${beijingCoordinate.guanghuEraDay}` : '北京时间正在流动'} onClick={openEraTimeline}/>}
<LakePool className="channel-status" title="湖面天气" meta={connectionLabel} onClick={() => openWorldTool('system')}/>
</section>}
{worldStage === 'lightLake' && repoLogin.domain === 'FIFTH_DOMAIN' && <section className="channel-world light-lake-world">
@ -1463,6 +1534,7 @@ function HoloLakeApp() {
</section>}
</main>
<footer className="world-footer"><b> · </b><span>GH-AIOS</span></footer>
{eraOpen && eraTimeline && <EraTimelineOverlay timeline={eraTimeline} coordinate={beijingCoordinate} onClose={() => setEraOpen(false)}/>}
{enterpriseEntryBusy && <div className="enterprise-gate"><section><p></p></section></div>}
{enterpriseRelationshipPending && enterpriseEntry && <div className="enterprise-gate"><section className="enterprise-receipt-panel" role="dialog" aria-modal="true">
<span className="receipt-step"> · </span><h2>{enterpriseEntry.subject.name}</h2><p>AGE </p>