From 0a12fc110bcdb1d9445d425ed8d33dca1effa6b2 Mon Sep 17 00:00:00 2001
From: DTALEX66 <151195992+DTALEX66@users.noreply.github.com>
Date: Tue, 28 Jul 2026 00:44:27 +0800
Subject: [PATCH 1/5] fix(ci): install playwright for test collection
---
requirements-ci.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/requirements-ci.txt b/requirements-ci.txt
index c24376d..e83177e 100644
--- a/requirements-ci.txt
+++ b/requirements-ci.txt
@@ -13,6 +13,7 @@ numpy>=1.24
pillow>=10.0
pydantic>=2.0
pytest>=7.0
+playwright>=1.61,<1.62
pytesseract>=0.3.13
python-multipart>=0.0.20
pyyaml>=6.0
From d5418d698a084fb22126fe6d04be6b157b51a95d Mon Sep 17 00:00:00 2001
From: DTALEX66 <151195992+DTALEX66@users.noreply.github.com>
Date: Tue, 28 Jul 2026 08:05:07 +0800
Subject: [PATCH 2/5] feat(workspace): add Violet Core desktop shell
---
README.md | 2 +-
app/workspace/ui/assets/app.js | 17 +++++++++++++----
app/workspace/ui/assets/styles.css | 8 ++++++++
app/workspace/ui/index.html | 30 +++++++++++++++++++++++++-----
docs/PROJECT_STATUS.md | 6 +++---
scripts/a0_browser_smoke.py | 18 ++++++++++++++++++
6 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index 7e1e72c..0d761a9 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
- **真实 Workspace 基础链**:网页、GitHub URL、本地文件导入 → candidate Research/Evidence → Knowledge/Learning/Mastery 治理;执行侧当前以 `read file:` 受限 Planner tracer 和局部闭环为主。
- **可治理的运行时**:SQLite 持久化、Outbox/Receipt、失败不改状态、重试与回读,以及不暴露内部审计 ID 的公开投影。
-- **双端验证**:CI 已包含 Windows Tauri 构建、运行时和 NSIS 生命周期门禁;本地真实 HTTP → SQLite → Chromium upload → dispatch → receipt → reload smoke 已通过,Tauri WebView 点击级证据和公开发布资产仍在收口。
+- **桌面 Workspace A1**:当前分支已接入 Violet Core 紫曜桌面壳、一级模块 Rail、动态二级导航、认知 Inspector 和真实活动坞;真实 Chromium 已验证壳层交互、响应式布局以及 HTTP → SQLite → Chromium upload → dispatch → receipt → reload 链路。Tauri WebView 点击级证据和公开发布资产仍在收口,不能用 Chromium 结果替代。
- **当前版本**:`0.4.0`;Release Manifest 仍为 `unreleased / public=false`,公开 Alpha/Beta/Stable 发布尚未宣告。
Research candidate 仍必须经过人工审查和来源独立性验证,不能自动当作 verified truth。当前事实、限制和验证证据见 [`docs/PROJECT_STATUS.md`](docs/PROJECT_STATUS.md) 与 [`docs/VERIFICATION_POLICY.md`](docs/VERIFICATION_POLICY.md)。
diff --git a/app/workspace/ui/assets/app.js b/app/workspace/ui/assets/app.js
index b0a204d..532d5ea 100644
--- a/app/workspace/ui/assets/app.js
+++ b/app/workspace/ui/assets/app.js
@@ -1,10 +1,12 @@
const $=selector=>document.querySelector(selector),$$=selector=>[...document.querySelectorAll(selector)];
-const state={theme:localStorage.getItem('aa-theme')||'yaojin',page:'overview',intakeTrigger:null};
+const state={theme:localStorage.getItem('aa-theme')||'violet-core',page:'overview',module:localStorage.getItem('aa-module')||'guanxin',intakeTrigger:null,inspectorCollapsed:localStorage.getItem('aa-inspector')==='collapsed',dockCollapsed:localStorage.getItem('aa-dock')==='collapsed'};
const icons={home:'M3 11l9-8 9 8v10a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1z',folder:'M3 6h6l2 2h10v12H3z',search:'M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16zm11 3-5-5',shield:'M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z',book:'M4 4h6a4 4 0 0 1 4 4v12a3 3 0 0 0-3-3H4zM20 4h-6',brain:'M8 4a4 4 0 0 0-4 4v1a4 4 0 0 0 0 8v1a4 4 0 0 0 4 4h1V4zM16 4a4 4 0 0 1 4 4v1a4 4 0 0 1 0 8v1a4 4 0 0 1-4 4h-1V4z',eye:'M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',layers:'M12 2 2 7l10 5 10-5zM2 17l10 5 10-5M2 12l10 5 10-5',cpu:'M6 6h12v12H6zM9 1v5M15 1v5M9 18v5M15 18v5M1 9h5M1 15h5M18 9h5M18 15h5',zap:'M13 2 3 14h8l-1 8 10-12h-8z',clock:'M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18zm0-13v5l3 2',tool:'M14 7a4 4 0 0 1 5-5l-3 3 2 2 3-3a4 4 0 0 1-5 5L7 18a2 2 0 0 1-3-3z',settings:'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm8-3a8 8 0 0 0-.2-1.8l2-1.6-2-3.4-2.4 1a8 8 0 0 0-3-1.8L14 2h-4l-.4 2.4a8 8 0 0 0-3 1.8l-2.4-1-2 3.4 2 1.6A8 8 0 0 0 4 12c0 .6.1 1.2.2 1.8l-2 1.6 2 3.4 2.4-1a8 8 0 0 0 3 1.8L10 22h4l.4-2.4a8 8 0 0 0 3-1.8l2 1.6c.1-.6.2-1.2.2-1.8z',activity:'M3 12h4l3 8 4-16 3 8h4',archive:'M3 4h18v5H3zm2 5v11h14V9M10 13h4',map:'M9 4 3 6v14l6-2 6 2 6-2V4l-6 2zm0 0v14m6-12v14',play:'M5 3l16 9-16 9z',list:'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01'};
function iconElement(name){const namespace='http://www.w3.org/2000/svg';const svg=document.createElementNS(namespace,'svg');svg.setAttribute('viewBox','0 0 24 24');svg.setAttribute('aria-hidden','true');const path=document.createElementNS(namespace,'path');path.setAttribute('d',icons[name]||icons.folder);svg.append(path);return svg}
-const nav=[['Core',[['overview','观心总览','Overview','home'],['projects','项目','Projects','folder'],['research','察微研究','Research','search'],['evidence','证据中心','Evidence','shield'],['knowledge','藏识知识','Knowledge','archive'],['machine','知衡机器知识','Machine','cpu'],['runtime','知行任务执行','Runtime','zap'],['evolution','知新评估进化','Evolution','activity']]],['Learning OS',[['courses','课程中心','Courses','book'],['learning','学习路线','Learning','map'],['review','复习','Review','clock'],['training','训练','Training','play'],['visual','显象可视化教学','Visual','layers'],['palace','知境空间宫殿','Palace','map'],['skills','技能实战','Skills','tool'],['teachback','输出教学','Teach Back','eye'],['consolidation','长期巩固','Consolidation','archive'],['report','学习报告','Report','list']]],['System',[['models','模型与工具','Models','cpu'],['agents','Agent管理','Agents','brain'],['audit','审计记录','Audit','shield'],['diagnostics','系统诊断','Diagnostics','activity'],['settings','设置','Settings','settings']]]];
-function renderNav(){const target=$('#nav');target.textContent='';nav.forEach(([group,items])=>{const section=document.createElement('section');section.className='nav-group';const title=document.createElement('div');title.className='nav-title';const groupName=document.createElement('span');groupName.textContent=group;const separator=document.createElement('span');separator.textContent='—';title.append(groupName,separator);section.append(title);items.forEach(item=>{const button=document.createElement('button');const active=state.page===item[0];button.type='button';button.className=`nav-item ${active?'active':''}`;button.dataset.page=item[0];button.title=item[1];if(active)button.setAttribute('aria-current','page');const chinese=document.createElement('span');chinese.className='cn';chinese.textContent=item[1];const english=document.createElement('span');english.className='en';english.textContent=item[2];button.append(iconElement(item[3]),chinese,english);section.append(button)});target.append(section)})}
-function setTheme(theme){const selected=['yaojin','deepspace'].includes(theme)?theme:'yaojin';state.theme=selected;localStorage.setItem('aa-theme',selected);document.body.dataset.theme=selected;$$('.theme button').forEach(button=>{const active=button.dataset.theme===selected;button.classList.toggle('active',active);button.setAttribute('aria-pressed',String(active));button.type='button'})}
+const nav=[['观心',[['overview','观心总览','Overview','home'],['projects','项目','Projects','folder']]],['知行',[['runtime','知行任务执行','Runtime','zap'],['delivery','投递回执','Delivery','archive']]],['察微',[['research','察微研究','Research','search'],['evidence','证据中心','Evidence','shield']]],['藏识',[['knowledge','藏识知识','Knowledge','archive'],['learning','学习路线','Learning','map'],['evolution','知新评估进化','Evolution','activity'],['machine','知衡机器知识','Machine','cpu']]],['智体',[['agents','Agent管理','Agents','brain'],['skills','技能实战','Skills','tool'],['models','模型与工具','Models','cpu']]],['流程',[['workflow-builder','流程构建器','Builder','layers'],['workflow-runs','流程运行记录','Runs','clock']]],['连接',[['integrations','外部连接','Integrations','folder'],['mcp','MCP工具','MCP','tool']]],['系统',[['diagnostics','系统诊断','Diagnostics','activity'],['audit','审计记录','Audit','shield'],['settings','设置','Settings','settings']]]];
+const pageModule={overview:'guanxin',projects:'guanxin',runtime:'zhixing',delivery:'zhixing',research:'chawei',evidence:'chawei',knowledge:'cangshi',learning:'cangshi',evolution:'cangshi',machine:'cangshi',agents:'zhiti',skills:'zhiti',models:'zhiti','workflow-builder':'workflow','workflow-runs':'workflow',integrations:'connect',mcp:'connect',diagnostics:'system',audit:'system',settings:'system'};
+const groupModule={'观心':'guanxin','知行':'zhixing','察微':'chawei','藏识':'cangshi','智体':'zhiti','流程':'workflow','连接':'connect','系统':'system'};
+function renderNav(){const target=$('#nav');target.textContent='';state.module=pageModule[state.page]||state.module;localStorage.setItem('aa-module',state.module);$$('.rail-item').forEach(button=>{const active=button.dataset.module===state.module;button.classList.toggle('active',active);button.setAttribute('aria-current',active?'page':'false')});nav.forEach(([group,items])=>{const section=document.createElement('section');section.className='nav-group';section.dataset.module=groupModule[group];section.classList.toggle('active-group',section.dataset.module===state.module);const title=document.createElement('div');title.className='nav-title';const groupName=document.createElement('span');groupName.textContent=group;const separator=document.createElement('span');separator.textContent='—';title.append(groupName,separator);section.append(title);items.forEach(item=>{const button=document.createElement('button');const active=state.page===item[0];button.type='button';button.className=`nav-item ${active?'active':''}`;button.dataset.page=item[0];button.title=item[1];if(active)button.setAttribute('aria-current','page');const chinese=document.createElement('span');chinese.className='cn';chinese.textContent=item[1];const english=document.createElement('span');english.className='en';english.textContent=item[2];button.append(iconElement(item[3]),chinese,english);section.append(button)});target.append(section)})}
+function setTheme(theme){const selected=['violet-core','yaojin','deepspace'].includes(theme)?theme:'violet-core';state.theme=selected;localStorage.setItem('aa-theme',selected);document.body.dataset.theme=selected;$$('.theme button').forEach(button=>{const active=button.dataset.theme===selected;button.classList.toggle('active',active);button.setAttribute('aria-pressed',String(active));button.type='button'})}
function metric(label,value,detail,tone='info'){const card=document.createElement('div');card.className='card metric';const name=document.createElement('span');name.textContent=label;const number=document.createElement('b');number.textContent=String(value);const note=document.createElement('span');note.className=`delta ${tone}`;note.textContent=detail;card.append(name,number,note);return card}
const capabilityLabels={asynchronous_worker:'异步Worker',outbox_dispatcher:'Outbox投递器',server_sent_events:'实时事件流',interactive_job_center:'交互式Job Center',asr_transcription:'ASR转写'};
const capabilityStates=new Set(['available','dependency_required','not_implemented']);
@@ -58,3 +60,10 @@ $('#intake-url-form').addEventListener('submit',async event=>{event.preventDefau
$('#intake-file-form').addEventListener('submit',async event=>{event.preventDefault();await runIntake(()=>fetch('/workspace/api/intake/upload',{method:'POST',body:new FormData(event.currentTarget)}))});
window.addEventListener('hashchange',()=>openPage(location.hash.slice(1)||'overview'));
setTheme(state.theme);openPage(location.hash.slice(1)||'overview');setInterval(()=>{$('#clock').textContent=new Date().toLocaleTimeString('zh-CN',{hour:'2-digit',minute:'2-digit',second:'2-digit'})},1000);setInterval(()=>{if(state.page==='runtime')void refreshRuntime();if(state.page==='evidence')void refreshLifecycle()},3000);
+
+function showShellToast(message){const toast=$('#toast');if(!toast)return;toast.textContent=message;toast.classList.add('show');window.clearTimeout(showShellToast.timer);showShellToast.timer=window.setTimeout(()=>toast.classList.remove('show'),2600)}
+function applyShellState(){document.body.classList.toggle('inspector-collapsed',state.inspectorCollapsed);document.body.classList.toggle('dock-collapsed',state.dockCollapsed);const inspector=$('.inspector');const inspectorButton=$('[data-action="inspector-toggle"]');const dockButton=$('[data-action="dock-toggle"]');if(inspector)inspector.classList.toggle('open',!state.inspectorCollapsed);if(inspectorButton)inspectorButton.textContent=state.inspectorCollapsed?'◧':'×';if(dockButton)dockButton.textContent=state.dockCollapsed?'⌃':'⌄';if(inspectorButton)inspectorButton.setAttribute('aria-label',state.inspectorCollapsed?'展开认知检查器':'折叠认知检查器');if(dockButton)dockButton.setAttribute('aria-label',state.dockCollapsed?'展开活动坞':'折叠活动坞')}
+function setModule(module){const group=nav.find(([name])=>groupModule[name]===module);if(!group)return;state.module=module;localStorage.setItem('aa-module',module);const firstPage=group[1][0][0];openPage(firstPage);$('.subnav')?.scrollTo({top:0,behavior:'smooth'})}
+async function refreshActivityDock(){try{const [jobs,delivery,research]=await Promise.all([fetchJson('/workspace/api/jobs').then(validateJobs),fetchJson('/workspace/api/delivery').then(validateDelivery),fetchJson('/workspace/api/research')]);const reviewCount=Array.isArray(research.items)?research.items.length:0;const pending=(delivery.summary.outbox?.pending||0)+(delivery.summary.outbox?.failed||0);$('#dock-jobs').textContent=String(jobs.jobs.length);$('#dock-delivery').textContent=`${pending} / ${delivery.summary.receipts?.recorded||0}`;$('#dock-review').textContent=String(reviewCount);$('#dock-summary').textContent=`${jobs.jobs.length} jobs · ${pending} pending/failed · ${reviewCount} review`;$('#inspector-status').textContent='本地 API 可读';$('#inspector-evidence').textContent=`${delivery.summary.receipts?.recorded||0} receipts`}catch{$('#dock-summary').textContent='真实活动读取失败';$('#dock-jobs').textContent='不可用';$('#dock-delivery').textContent='不可用';$('#dock-review').textContent='不可用';$('#inspector-status').textContent='不可用';$('#inspector-evidence').textContent='等待重新读取'}}
+document.addEventListener('click',event=>{const rail=event.target.closest('[data-module]');if(rail){setModule(rail.dataset.module);return}const action=event.target.closest('[data-action]');if(!action)return;if(action.dataset.action==='inspector-toggle'){state.inspectorCollapsed=!state.inspectorCollapsed;localStorage.setItem('aa-inspector',state.inspectorCollapsed?'collapsed':'open');applyShellState();return}if(action.dataset.action==='dock-toggle'){state.dockCollapsed=!state.dockCollapsed;localStorage.setItem('aa-dock',state.dockCollapsed?'collapsed':'open');applyShellState();return}if(action.dataset.action==='command-open'){showShellToast('全局命令入口规划中;当前请使用左侧真实工作区入口');$('#global-search')?.focus();return}});
+applyShellState();void refreshActivityDock();setInterval(()=>void refreshActivityDock(),3000);
diff --git a/app/workspace/ui/assets/styles.css b/app/workspace/ui/assets/styles.css
index a455eca..297c80b 100644
--- a/app/workspace/ui/assets/styles.css
+++ b/app/workspace/ui/assets/styles.css
@@ -10,3 +10,11 @@ body[data-theme='deepspace']{--bg:#0A0E1A;--deep:#060911;--panel:#121726;--panel
.editor{display:grid;grid-template-columns:220px minmax(0,1fr) 320px;grid-template-rows:auto minmax(480px,1fr) 58px;gap:0;border:1px solid var(--line);border-radius:var(--r3);overflow:hidden;background:var(--panel2);height:680px}.editor-top{grid-column:1/-1;height:48px;display:flex;align-items:center;gap:8px;padding:0 12px;border-bottom:1px solid var(--line);background:var(--panel)}.editor-left{border-right:1px solid var(--line);overflow:auto}.editor-canvas{position:relative;background-image:radial-gradient(circle,var(--line) 1px,transparent 1px);background-size:22px 22px;overflow:auto}.editor-right{border-left:1px solid var(--line);overflow:auto}.editor-bottom{grid-column:1/-1;display:flex;align-items:center;gap:10px;border-top:1px solid var(--line);padding:0 12px;background:var(--panel)}.node{position:absolute;min-width:150px;border:1px solid var(--line2);border-radius:9px;background:var(--panel);box-shadow:var(--shadow);padding:10px}.node b{display:block}.node span{color:var(--muted);font-size:11px}.node.fact{border-color:var(--info)}.node.memory{border-color:var(--accent)}.node.teach{border-color:var(--ok)}.edge{position:absolute;height:1px;background:var(--line2);transform-origin:left center}.palace{position:relative;height:620px;background:radial-gradient(circle at 50% 30%,var(--panel3),var(--deep));border:1px solid var(--line);border-radius:var(--r3);overflow:hidden;perspective:900px}.room{position:absolute;border:1px solid var(--line2);background:linear-gradient(180deg,var(--panel),var(--panel2));border-radius:10px;padding:10px;transform:rotateX(55deg) rotateZ(-8deg);box-shadow:var(--shadow)}.room:after{content:'';position:absolute;inset:8px;border:1px dashed var(--line);border-radius:6px}.locus{position:absolute;width:16px;height:16px;border-radius:50%;background:var(--accent);border:3px solid var(--deep);box-shadow:0 0 0 2px var(--accent)}.route{position:absolute;height:2px;background:linear-gradient(90deg,transparent,var(--accent),transparent)}
.runtime{display:grid;grid-template-columns:260px minmax(0,1fr) 340px;grid-template-rows:auto minmax(0,1fr) 190px;gap:var(--gap);height:720px}.runtime-head{grid-column:1/-1}.runtime-trace{grid-column:1/-1}.step{display:flex;gap:9px;padding:10px;border:1px solid var(--line);border-radius:8px;margin-bottom:8px;background:var(--panel2)}.step .n{width:22px;height:22px;border-radius:50%;background:var(--deep);border:1px solid var(--line2);display:grid;place-items:center;font:700 10px var(--mono);color:var(--accent)}.step.active{border-color:var(--accent);background:var(--soft)}.log{height:100%;overflow:auto;background:var(--deep);border:1px solid var(--line);border-radius:8px;padding:12px;font:12px/1.6 var(--mono)}.log .t{color:var(--muted)}.log .tool{color:var(--info)}.log .ok{color:var(--ok)}.log .warn{color:var(--warn)}.log .bad{color:var(--bad)}.permission{border:1px solid var(--warn);background:color-mix(in srgb,var(--warn) 9%,var(--panel));border-radius:8px;padding:12px}.job{position:fixed;left:var(--nav-w);right:0;bottom:0;height:var(--job-h);background:var(--glass);backdrop-filter:blur(14px);border-top:1px solid var(--line);z-index:25;display:grid;grid-template-columns:220px minmax(0,1fr) 220px}.job-title{padding:14px 16px;border-right:1px solid var(--line)}.job.collapsed{height:64px;grid-template-columns:minmax(0,1fr) 180px;overflow:hidden}.job.collapsed .job-list{display:none}.job.collapsed .job-title{border-right:0}.job.collapsed .job-actions{padding:10px;border-left:1px solid var(--line)}.job-list{padding:10px 16px;overflow:auto}.job-actions{border-left:1px solid var(--line);padding:14px}.job-row{display:grid;grid-template-columns:180px minmax(0,1fr) 150px 130px;align-items:center;gap:12px;padding:8px 0;border-bottom:1px solid var(--line)}.job-row:last-child{border-bottom:0}.drawer{position:fixed;top:var(--top-h);right:0;bottom:var(--job-h);width:420px;background:var(--glass);backdrop-filter:blur(18px);border-left:1px solid var(--line);z-index:35;transform:translateX(100%);transition:transform .18s ease;box-shadow:var(--shadow)}.drawer.open{transform:none}.drawer-head{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid var(--line)}.drawer-body{padding:16px;overflow:auto;height:calc(100% - 58px)}.kv{display:grid;grid-template-columns:110px 1fr;gap:9px 12px;margin-bottom:16px}.kv dt{color:var(--muted);font-size:12px}.kv dd{margin:0;min-width:0;overflow-wrap:anywhere}.modal{position:fixed;inset:0;background:rgba(0,0,0,.48);display:none;place-items:center;padding:16px;z-index:60}.modal.open{display:grid}.dialog{width:min(560px,100%);max-height:calc(100dvh - 32px);overflow:auto;background:var(--panel);border:1px solid var(--line2);border-radius:12px;box-shadow:var(--shadow);padding:18px}.palette{position:fixed;inset:0;background:rgba(0,0,0,.42);display:none;z-index:70}.palette.open{display:block}.palette-box{width:min(720px,92vw);margin:10vh auto 0;background:var(--glass);backdrop-filter:blur(20px);border:1px solid var(--line2);border-radius:12px;box-shadow:var(--shadow);overflow:hidden}.palette-box input{width:100%;height:50px;background:transparent;border:0;border-bottom:1px solid var(--line);padding:0 16px;outline:none;font-size:16px}.palette-item{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--line)}.palette-item:hover{background:var(--soft)}.empty{border:1px dashed var(--line2);border-radius:10px;padding:26px;text-align:center;color:var(--muted)}.empty b{display:block;color:var(--text);font-size:16px;margin-bottom:6px}.toast{position:fixed;right:22px;bottom:calc(var(--job-h) + 20px);background:var(--panel);border:1px solid var(--line2);border-radius:9px;padding:11px 13px;box-shadow:var(--shadow);z-index:80;display:none}.toast.show{display:block}.mono{font-family:var(--mono)}.gold{color:var(--accent)}.muted{color:var(--muted)}.ok{color:var(--ok)}.warn{color:var(--warn)}.bad{color:var(--bad)}.info{color:var(--info)}.view-switch{display:flex;border:1px solid var(--line);border-radius:7px;overflow:hidden}.view-switch button{border:0;background:var(--panel2);padding:6px 9px;color:var(--muted)}.view-switch button.active{background:var(--accent);color:var(--deep);font-weight:700}.filterbar{display:flex;gap:8px;align-items:center;margin-bottom:12px}.filterbar input,.filterbar select{height:34px;border:1px solid var(--line);border-radius:7px;background:var(--panel2);padding:0 9px}.form{display:grid;gap:12px}.field{display:grid;gap:6px}.field label{font-weight:700}.field input,.field textarea,.field select{border:1px solid var(--line);border-radius:7px;background:var(--deep);padding:9px 10px;min-width:0}.field textarea{min-height:100px;resize:vertical}.result{display:none;max-height:220px;margin:12px 0 0;padding:10px;border:1px solid var(--line);border-radius:7px;background:var(--deep);overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere}.segmented{display:flex;gap:6px;flex-wrap:wrap}.segmented button{border:1px solid var(--line);background:var(--panel2);border-radius:999px;padding:6px 10px;color:var(--muted)}.segmented button.active{color:var(--accent);border-color:var(--accent);background:var(--soft)}
@media(max-width:1440px){:root{--nav-w:220px}.grid.cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}.split{grid-template-columns:240px minmax(0,1fr) 340px}.drawer{width:380px}.main{padding-left:20px;padding-right:20px}}@media(max-width:1280px){:root{--nav-w:72px;--top-h:56px;--job-h:150px}.brand-name,.brand-sub,.workspace-pill span,.project-pill,.user .meta,.nav-title,.nav-item .cn,.nav-item .en{display:none}.brand{width:54px;justify-content:center}.nav{padding-left:8px;padding-right:8px}.nav-item{justify-content:center;padding:9px}.grid.cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}.grid.cols-3{grid-template-columns:repeat(2,minmax(0,1fr))}.split{grid-template-columns:220px minmax(0,1fr)}.split .pane:last-child{grid-column:1/-1}.editor{grid-template-columns:190px minmax(0,1fr);grid-template-rows:auto minmax(420px,1fr) auto auto}.editor-right{grid-column:1/-1;border-left:0;border-top:1px solid var(--line);max-height:220px}.runtime{grid-template-columns:220px minmax(0,1fr);height:auto}.runtime>aside:last-of-type{grid-column:1/-1}.runtime-trace{min-height:220px}.drawer{width:360px}.job-row{grid-template-columns:150px minmax(0,1fr) 120px}}@media(min-width:1800px){:root{--nav-w:256px}.main{padding-left:32px;padding-right:32px}.grid.cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.card{padding:18px}.page h1{font-size:30px}}
+body[data-theme='violet-core']{--bg:#070A13;--deep:#0B1020;--panel:#10172A;--panel2:#141D34;--panel3:#1A2540;--text:#F3F5FA;--muted:#A3ACC0;--line:rgba(155,121,255,.16);--line2:rgba(155,121,255,.36);--accent:#7C5CFF;--accent2:#AA76FF;--soft:rgba(124,92,255,.13);--ok:#4DBB84;--warn:#D8A84E;--bad:#D65A67;--info:#4DB7FF;--glass:rgba(7,10,19,.9);--shadow:0 18px 46px rgba(0,0,0,.34)}
+/* AXDESK-A1: the Violet Core desktop shell. */
+:root{--rail-w:62px;--subnav-w:242px;--shell-dock-h:156px;--shell-inspector-w:326px}
+.top{height:var(--top-h);padding:0 14px 0 16px;gap:10px}.brand{width:210px;flex:0 0 210px}.brand-name{letter-spacing:.04em}.top-tabs{display:flex;align-items:center;gap:3px;height:30px;border:1px solid var(--line);border-radius:8px;padding:3px;background:var(--deep);white-space:nowrap}.top-tab{padding:5px 9px;border-radius:5px;font-size:12px}.top-tab.active{background:var(--soft);color:var(--accent);font-weight:700}.muted-tab{color:var(--muted)}.command-btn{height:34px;border:1px solid var(--line2);border-radius:7px;background:var(--soft);color:var(--accent);font-size:12px;padding:0 10px;white-space:nowrap}.rail{position:fixed;left:0;top:var(--top-h);bottom:0;width:var(--rail-w);z-index:31;padding:10px 6px;border-right:1px solid var(--line);background:linear-gradient(180deg,var(--deep),var(--panel2));display:flex;flex-direction:column;gap:5px}.rail-item{display:grid;place-items:center;gap:2px;min-height:48px;border:1px solid transparent;border-radius:8px;background:transparent;color:var(--muted);font-size:10px;padding:5px 2px}.rail-item:hover{background:var(--panel3);color:var(--text)}.rail-item.active{border-color:var(--line2);background:var(--soft);color:var(--accent)}.rail-glyph{font-size:18px;line-height:1;font-family:var(--font-ui)}.subnav{left:var(--rail-w);width:var(--subnav-w);padding:13px 10px 18px;background:linear-gradient(180deg,var(--deep),var(--panel2));z-index:29}.subnav .nav-group{display:none}.subnav .nav-group[data-module].active-group{display:block}.main{margin-left:calc(var(--rail-w) + var(--subnav-w));padding:calc(var(--top-h) + 18px) calc(var(--shell-inspector-w) + 24px) calc(var(--shell-dock-h) + 28px) 24px}.inspector{position:fixed;right:0;top:var(--top-h);bottom:var(--shell-dock-h);width:var(--shell-inspector-w);z-index:28;border-left:1px solid var(--line);background:linear-gradient(180deg,var(--panel2),var(--deep));overflow:auto;transition:transform .18s ease}.inspector-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:14px;border-bottom:1px solid var(--line)}.inspector-head b{display:block;margin-top:4px}.inspector-body{padding:14px}.inspector-core{display:grid;gap:4px;padding:14px;border:1px solid var(--line2);border-radius:10px;background:radial-gradient(circle at 50% 0,var(--soft),transparent 65%),var(--panel);margin-bottom:14px}.core-orb{font-size:30px;color:var(--accent);text-shadow:0 0 22px var(--accent);line-height:1}.inspector-list{display:grid;gap:0;border:1px solid var(--line);border-radius:8px;overflow:hidden}.inspector-list>div{display:grid;gap:2px;padding:10px;border-bottom:1px solid var(--line)}.inspector-list>div:last-child{border-bottom:0}.inspector-list span{font:10px var(--mono);color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.inspector-list b{font-size:12px;overflow-wrap:anywhere}.small{font-size:11px}.activity-dock{position:fixed;left:calc(var(--rail-w) + var(--subnav-w));right:0;bottom:0;height:var(--shell-dock-h);z-index:27;border-top:1px solid var(--line2);background:var(--glass);backdrop-filter:blur(16px);transition:height .18s ease}.dock-head{height:42px;display:flex;align-items:center;justify-content:space-between;padding:0 14px;border-bottom:1px solid var(--line)}.dock-brand,.dock-actions{display:flex;align-items:center;gap:8px}.dock-pulse{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 3px var(--soft),0 0 12px var(--accent)}.dock-body{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;padding:10px 14px}.dock-card{display:grid;gap:3px;min-width:0;padding:9px 11px;border:1px solid var(--line);border-radius:8px;background:var(--panel2)}.dock-card b{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dock-card>span:last-child{font-size:11px;color:var(--muted)}.dock-label{font:10px var(--mono);color:var(--accent);letter-spacing:.08em}.dock-note{border-style:dashed}.toast{bottom:calc(var(--shell-dock-h) + 16px)}body.inspector-collapsed .inspector{transform:none;width:42px;overflow:hidden}.inspector-collapsed .inspector-head{padding:10px 4px;justify-content:center}.inspector-collapsed .inspector-head>div,.inspector-collapsed .inspector-body{display:none}body.inspector-collapsed .main{padding-right:24px}body.dock-collapsed{--shell-dock-h:42px}body.dock-collapsed .dock-body{display:none}.theme button.active{background:var(--soft);color:var(--accent);font-weight:700}
+@media(max-width:1280px){:root{--rail-w:58px;--subnav-w:210px;--shell-inspector-w:280px}.brand{width:170px;flex-basis:170px}.top-tabs{display:none}.main{padding-right:calc(var(--shell-inspector-w) + 18px);padding-left:18px}.subnav .nav-title{display:flex}.subnav .nav-item .cn,.subnav .nav-item .en{display:inline}.rail-item{min-height:44px}.dock-body{grid-template-columns:repeat(3,minmax(0,1fr))}.dock-note{display:none}}
+@media(max-width:960px){:root{--rail-w:54px;--subnav-w:0px;--shell-dock-h:116px}.subnav{transform:translateX(-100%);transition:transform .18s ease}.subnav:focus-within,.subnav:hover{transform:none;box-shadow:var(--shadow)}.main{margin-left:var(--rail-w);padding:calc(var(--top-h) + 14px) 14px calc(var(--shell-dock-h) + 18px)}.inspector{width:min(326px,88vw);bottom:var(--shell-dock-h);transform:translateX(100%)}.inspector.open{transform:none}.activity-dock{left:var(--rail-w)}.brand{width:38px;flex-basis:38px}.brand-name,.brand-sub,.workspace-pill,.chip,.user .meta,.search{display:none}.command-btn{margin-left:auto}.dock-body{grid-template-columns:repeat(3,minmax(0,1fr));padding:7px 10px}.dock-card{padding:7px}.dock-card:nth-child(3){display:none}}
+@media(max-width:520px){:root{--top-h:54px;--shell-dock-h:106px}.top{padding:0 8px;gap:6px}.command-btn{font-size:0;width:34px;padding:0}.command-btn:before{content:'⌘';font-size:16px}.theme{display:none}.icon-btn{min-width:32px}.main{padding-left:10px;padding-right:10px}.page-head{align-items:flex-start;flex-direction:column}.head-actions{width:100%;flex-wrap:wrap}.grid.cols-2,.grid.cols-3,.grid.cols-4{grid-template-columns:1fr}.dock-head{padding:0 9px}.dock-body{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;padding:6px 8px}.dock-card:nth-child(4){display:none}.dock-card b{font-size:11px}.dock-card>span:last-child{font-size:10px}.dock-brand .muted{display:none}}
+@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
diff --git a/app/workspace/ui/index.html b/app/workspace/ui/index.html
index b34d508..8a98439 100644
--- a/app/workspace/ui/index.html
+++ b/app/workspace/ui/index.html
@@ -6,18 +6,30 @@
元枢系统 ArcheAxis OS · 元枢·观心
-
+
-
+
+ 观心工作台本地运行时+ 规划中
元枢·观心LOCAL ONLY
- A0
+ A0
+
本地工作台
-
+
-
+
+
GUANXIN OVERVIEW
观心总览
只展示本机数据库和发布清单可证明的状态;没有证据的数据不会出现在这里。
@@ -74,6 +86,14 @@
尚未接入真实数据不会展示样例数量、虚构进度、伪服务状态或不可执行按钮。
+
+
+
+ JOB读取中真实任务
DELIVERY读取中待投递 / 失败
REVIEW读取中待人工复核
TRUTH BOUNDARY不显示伪进度状态来自本地 API
+
粘贴网页地址或选择本地文件。系统自动处理,不要求填写内部编号。
或
diff --git a/docs/PROJECT_STATUS.md b/docs/PROJECT_STATUS.md
index 21a6449..c00e9fb 100644
--- a/docs/PROJECT_STATUS.md
+++ b/docs/PROJECT_STATUS.md
@@ -1,10 +1,10 @@
# 项目当前状态
-> 更新:2026-07-27。本页是能力状态入口;旧审计文件是历史快照。机器无关的恢复检查见 [`HANDOFF_2026-07-21.md`](HANDOFF_2026-07-21.md),实时分支、SHA、dirty 状态与 CI 必须从 Git/GitHub 读取。
+> 更新:2026-07-28。本页是能力状态入口;旧审计文件是历史快照。机器无关的恢复检查见 [`HANDOFF_2026-07-21.md`](HANDOFF_2026-07-21.md),实时分支、SHA、dirty 状态与 CI 必须从 Git/GitHub 读取。
## 当前阶段
-历史 **Phase 9:Contract & Tracer Alpha** 已完成,但不代表完整产品 Alpha。当前处于 ArcheAxis Product Stage A0 真相基线收口期:GitHub/普通网页/本地文件 Research,以及 Knowledge/Learning/Mastery/Machine Knowledge 的后端治理构件已有真实路径;Planner 只有 `read file:` 首条受限 tracer,统一 Runtime/Sleep Loop、Reviewed Feedback 和通用 Planner 尚未完成。本地 Workspace 已具备打包页面、loopback-only 写入、真实导入入口、只返回聚合事实的状态接口,以及不暴露内部 ID 的 Job/Delivery 投影。Workspace Job/Outbox migration owner、同事务写入、同步终态、严格 readback、按需 dispatcher、服务级 lease/retry 和 receipt 已交付;本地真实 Chromium upload → dispatch → receipt → reload 门禁已验证,Tauri WebView 点击级验收、统一 Audit、SSE、异步 Worker 与交互式 Job Center 仍未完成。图像 OCR 基础依赖、真实图像门禁、Windows 构建和 NSIS 生命周期门禁已验证;ASR、公开 Installer 资产、多端发布及公开 Alpha/Beta/Stable 尚未完成。外部来源仍只形成可追溯、持久化且必须复核的 candidate,不能自动提升为 verified truth。
+历史 **Phase 9:Contract & Tracer Alpha** 已完成,但不代表完整产品 Alpha。当前处于 ArcheAxis Product Stage A0 真相基线收口期:GitHub/普通网页/本地文件 Research,以及 Knowledge/Learning/Mastery/Machine Knowledge 的后端治理构件已有真实路径;Planner 只有 `read file:` 首条受限 tracer,统一 Runtime/Sleep Loop、Reviewed Feedback 和通用 Planner 尚未完成。本地 Workspace 已具备打包页面、loopback-only 写入、真实导入入口、只返回聚合事实的状态接口,以及不暴露内部 ID 的 Job/Delivery 投影。A1 桌面壳已在当前分支接入 Violet Core 紫曜主题、一级 Rail、动态二级导航、认知 Inspector 和真实活动坞,并通过当前树 Chromium smoke 验证;Workspace Job/Outbox migration owner、同事务写入、同步终态、严格 readback、按需 dispatcher、服务级 lease/retry 和 receipt 已交付。Tauri WebView 点击级验收、统一 Audit、SSE、异步 Worker 与交互式 Job Center 仍未完成。图像 OCR 基础依赖、真实图像门禁、Windows 构建和 NSIS 生命周期门禁已验证;ASR、公开 Installer 资产、多端发布及公开 Alpha/Beta/Stable 尚未完成。外部来源仍只形成可追溯、持久化且必须复核的 candidate,不能自动提升为 verified truth。
## 已验证能力
@@ -25,7 +25,7 @@
- 外部 HTTP 调用已收敛到 Safe HTTP policy,覆盖私网/metadata/redirect/响应大小/类型/timeout;本地摄入与投影使用 approved roots 和 symlink/junction containment。
- 持久化哈希已使用 versioned SHA-256;Core、TaskPack、Vector、FTS、Research、Knowledge Governance 与 Workspace 共九个 owner 已统一注册到 migration operator。
- Workspace 可将普通网页、GitHub URL 与 approved-root 本地文件持久化为候选 ResearchPackage,并通过独立连接严格读回;浏览器写入仅允许 loopback,本地页面不收集 API key/JWT;本地 Chromium upload → dispatch → receipt → reload smoke 已验证。
-- Workspace 总览已移除静态运营数字和伪服务状态,只读取本地数据库聚合与 packaged unreleased Release Manifest;Job/Delivery 页面已提供真实 pending/delivered/receipt 聚合与按需操作,尚未接线的产品入口明确显示无真实数据。
+- Workspace 总览已移除静态运营数字和伪服务状态,只读取本地数据库聚合与 packaged unreleased Release Manifest;A1 Violet Core 壳层、Rail、二级导航、Inspector 和活动坞已通过真实 Chromium 交互/响应式 smoke;Job/Delivery 页面已提供真实 pending/delivered/receipt 聚合与按需操作,尚未接线的产品入口明确显示无真实数据。
- Learning 审批与卡片投影使用同事务持久收据;Runtime 只读取 approved Machine Knowledge,Machine Knowledge 审批/弃用使用 append-only migration-owned 收据并拒绝冲突重放。
- 媒体基础链已用真实 FFmpeg 验证 MP4 → 16 kHz mono PCM WAV、WAV 元数据读取和关键帧 PNG 尺寸核验;图像 OCR 基础适配器已用真实图片验证,ASR、媒体时间戳、内容匹配 Evidence 与人工真值准确率仍未闭环。
- n8n、Airflow、LiteLLM 和 crawler 适配器不再返回 stub 假成功。
diff --git a/scripts/a0_browser_smoke.py b/scripts/a0_browser_smoke.py
index ec5d5d3..0d0bc14 100644
--- a/scripts/a0_browser_smoke.py
+++ b/scripts/a0_browser_smoke.py
@@ -63,6 +63,24 @@ def exercise_workspace(page: Page, base_url: str) -> None:
page.get_by_role("heading", name="功能尚未接入").wait_for()
page.goto(f"{base_url}/workspace#overview", wait_until="networkidle")
+ assert page.locator("body").get_attribute("data-theme") == "violet-core"
+ assert page.get_by_role("complementary", name="一级模块").is_visible()
+ assert page.get_by_role("complementary", name="认知检查器").is_visible()
+ assert page.get_by_role("region", name="活动坞").is_visible()
+ assert page.get_by_role("button", name="折叠认知检查器").is_visible()
+ page.get_by_role("button", name="折叠认知检查器").click()
+ assert page.evaluate("document.body.classList.contains('inspector-collapsed')")
+ page.get_by_role("button", name="展开认知检查器").click()
+ assert not page.evaluate("document.body.classList.contains('inspector-collapsed')")
+ page.get_by_role("button", name="折叠活动坞").click()
+ assert page.evaluate("document.body.classList.contains('dock-collapsed')")
+ page.get_by_role("button", name="展开活动坞").click()
+ assert not page.evaluate("document.body.classList.contains('dock-collapsed')")
+ page.get_by_role("button", name="智体").click()
+ page.get_by_role("heading", name="Agent管理").wait_for()
+ assert "尚未接入真实数据" in page.locator("#page-unavailable").inner_text()
+ page.locator('.rail-item[title="观心"]').click()
+ page.get_by_role("heading", name="观心总览").wait_for()
page.get_by_text("异步Worker", exact=True).wait_for()
assert "尚未实现" in page.locator("#capability-summary").inner_text()
From 53573e91b2005334d4a8330a1e85a24938dd9b8a Mon Sep 17 00:00:00 2001
From: DTALEX66 <151195992+DTALEX66@users.noreply.github.com>
Date: Tue, 28 Jul 2026 20:32:17 +0800
Subject: [PATCH 3/5] fix(ci): cover adapter dependencies and ffmpeg
---
.github/workflows/ci.yml | 2 +-
requirements-ci.txt | 9 ++++++++-
tests/test_release_manifest.py | 6 +++++-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f83921c..0473095 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -38,7 +38,7 @@ jobs:
- name: Install and verify local OCR engine
run: |
sudo apt-get update
- sudo apt-get install --yes --no-install-recommends tesseract-ocr tesseract-ocr-eng fonts-dejavu-core
+ sudo apt-get install --yes --no-install-recommends ffmpeg tesseract-ocr tesseract-ocr-eng fonts-dejavu-core
tesseract --list-langs | grep --fixed-strings --line-regexp eng
- name: Run OS-level tests
diff --git a/requirements-ci.txt b/requirements-ci.txt
index e83177e..f6854b3 100644
--- a/requirements-ci.txt
+++ b/requirements-ci.txt
@@ -1,5 +1,7 @@
# Minimal dependencies required by CI test and lint jobs.
-# Runtime-only ingestion/LLM packages remain covered by wheel-smoke via requirements.txt.
+# Runtime-only ingestion/LLM packages remain covered by wheel-smoke via requirements.txt;
+# these adapter packages are also required because the OS-level contract tests exercise
+# their installed paths directly.
apscheduler>=3.10
beautifulsoup4>=4.11
defusedxml>=0.7.1
@@ -8,6 +10,8 @@ httpx2>=0.28
jinja2>=3.1,<4
jsonschema>=4.0
loguru>=0.7
+markitdown>=0.1
+newspaper4k>=0.9
networkx>=3.0
numpy>=1.24
pillow>=10.0
@@ -17,9 +21,12 @@ playwright>=1.61,<1.62
pytesseract>=0.3.13
python-multipart>=0.0.20
pyyaml>=6.0
+readabilipy>=0.3
requests>=2.28
ruff>=0.5
sqlite-vec>=0.1.6
structlog>=24.0
tomli>=2.0; python_version < "3.11"
+trafilatura>=1.6
uvicorn[standard]>=0.22
+youtube-transcript-api>=1.2
diff --git a/tests/test_release_manifest.py b/tests/test_release_manifest.py
index 5d2a9cd..36ae066 100644
--- a/tests/test_release_manifest.py
+++ b/tests/test_release_manifest.py
@@ -214,6 +214,7 @@ def test_release_checksum_script_refuses_no_artifacts(tmp_path) -> None:
def test_release_identity_injection_manifests_exact_commit_and_tree(tmp_path) -> None:
"""Verify scripts/release_inject_identity.py writes valid identity manifest."""
import json
+ import os
import subprocess
import sys
@@ -229,7 +230,10 @@ def test_release_identity_injection_manifests_exact_commit_and_tree(tmp_path) ->
"--tree", tree,
"--branch", "feat/absorption-roadmap-r0",
"--output", str(output)],
- capture_output=True, text=True, cwd=Path(__file__).resolve().parents[1],
+ capture_output=True,
+ text=True,
+ cwd=Path(__file__).resolve().parents[1],
+ env={key: value for key, value in os.environ.items() if key != "GITHUB_RUN_ID"},
)
assert result.returncode == 0, f"script failed: {result.stderr}"
From f1702990f808da1074a4aac461b24e6268ec9ec7 Mon Sep 17 00:00:00 2001
From: DTALEX66 <151195992+DTALEX66@users.noreply.github.com>
Date: Tue, 28 Jul 2026 20:54:23 +0800
Subject: [PATCH 4/5] fix(ci): isolate adapter test dependencies and align
rules
---
.github/workflows/ci.yml | 9 ++++++---
AGENTS.md | 23 ++++++++++-------------
docs/VERIFICATION_POLICY.md | 2 +-
requirements-ci-adapters.txt | 7 +++++++
requirements-ci.txt | 8 --------
5 files changed, 24 insertions(+), 25 deletions(-)
create mode 100644 requirements-ci-adapters.txt
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0473095..f826b74 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -30,11 +30,14 @@ jobs:
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
with:
enable-cache: true
- cache-dependency-glob: requirements-ci.txt
+ cache-dependency-glob: requirements-ci*.txt
- name: Install minimal test dependencies
run: uv pip install --system -r requirements-ci.txt
+ - name: Install adapter test dependencies
+ run: uv pip install --system -r requirements-ci-adapters.txt
+
- name: Install and verify local OCR engine
run: |
sudo apt-get update
@@ -67,7 +70,7 @@ jobs:
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
with:
enable-cache: true
- cache-dependency-glob: requirements-ci.txt
+ cache-dependency-glob: requirements-ci*.txt
- name: Install minimal lint dependencies
run: uv pip install --system -r requirements-ci.txt
@@ -346,7 +349,7 @@ jobs:
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
with:
enable-cache: true
- cache-dependency-glob: requirements-ci.txt
+ cache-dependency-glob: requirements-ci*.txt
- name: Install minimal runtime smoke dependencies
run: uv pip install --system -r requirements-ci.txt
- name: Migrate fresh Windows runtime
diff --git a/AGENTS.md b/AGENTS.md
index d8eff0b..0b88f07 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -2,6 +2,10 @@
This file is the public, sanitized operating configuration for Codex/agent work inside this repository. It describes how an agent should work on Cognitive-OS without exposing local credentials, private keys, tokens, machine-specific secrets, or personal files.
+## Rule ownership and precedence
+
+Global Hermes workflow rules own the general execution protocol: single-writer coordination, project-data containment, secret handling, safe editing, testing, and exact-SHA delivery. This file owns only Cognitive-Loop-OS-specific boundaries, architecture facts, and repository conventions. When a global rule and this file overlap, follow the stricter rule and keep the project wording as a concrete exception or example rather than duplicating the global procedure.
+
## 1. Project Mission
Cognitive-OS is the front runtime for two primary systems:
@@ -31,30 +35,25 @@ information -> attention -> understanding -> structure -> memory -> learning ->
| Configuration index | `workspace/configuration/README.md` | Catalog of public vs private configuration categories |
| Intake history | `workspace/intake/` | Stepwise design and implementation log |
-## 3. Safety Rules
+## 3. Project-Specific Safety Boundaries
-- Work inside the current repository unless the user explicitly names another exact project path.
- The external A project named `Obsidian-Assistance` is already audited and absorbed: do not scan, test, modify, synchronize, or use it as a migration target in future Cognitive-Loop-OS work.
- Do not access `E:\` unless the user explicitly confirms the exact path, action, and impact range.
-- Do not upload or print secrets: `.env`, `.codex`, SSH private keys, API keys, tokens, cookies, credentials, or password files.
-- Do not commit runtime memory, local caches, virtual environments, logs, or generated databases.
-- Project-owned outputs from Cognitive-OS code, tests, ingestion, builds, and reviews must use the project-local ignored runtime/build locations; a wrapper is the preferred containment path but is not an OS sandbox.
+- Project-owned outputs from Cognitive-OS code, tests, ingestion, builds, and reviews must use the project-local ignored runtime/build locations defined by the global project-data boundary; a wrapper is preferred but is not an OS sandbox.
- Do not claim ownership of Hermes, Codex, CC Switch, Workflow-assistance, GitHub delegation, session, cron, Kanban, or other workflow-infrastructure files merely because their names mention this project. Those artifacts remain in their owning workflow directory.
- Files found in `%TEMP%`, a user home, or another project are ambiguous until content, Git worktree, process, and generation command establish ownership; preserve and mark unresolved rather than delete or move them.
-- Prefer small, auditable changes that can be reverted with one commit.
-- Do not use destructive actions such as recursive deletion, hard reset, forced push, or mass overwrite unless the user separately confirms scope.
-## 4. Git Rules
+## 4. Project-Specific Git Conventions
Before modifying repository files:
-```powershell
+```bash
git status --short
```
After modifying repository files:
-```powershell
+```bash
git diff --stat
git status --short
```
@@ -62,9 +61,7 @@ git status --short
Upload policy:
- Use explicit paths when staging files.
-- Avoid `git add .`.
-- Do not commit or push unrelated local changes.
-- Do not force push.
+- Keep the working tree limited to the requested project scope; the global Git safety rules govern force pushes, destructive commands, and unrelated changes.
- Commit messages should describe the functional scope.
## 5. Network Rules
diff --git a/docs/VERIFICATION_POLICY.md b/docs/VERIFICATION_POLICY.md
index 72c5704..61820e2 100644
--- a/docs/VERIFICATION_POLICY.md
+++ b/docs/VERIFICATION_POLICY.md
@@ -74,7 +74,7 @@
## 本地与云端健康
-- 临时数据只能写入本仓库 `.tmp/`、测试专用目录或已忽略的构建目录;结束前删除。
+- 临时数据必须遵循全局 project-data boundary,统一写入本仓库 `.hermes/task-runtime/` 下对应任务的已忽略目录;不得使用 `%TEMP%`、用户目录或其他项目目录。
- 禁止验证命令读写其他项目或数据目录。
- 提交前要求无未暂存变更、无凭据、无运行时数据库或缓存泄漏。
- 推送后必须确认远端 SHA 与本地提交一致且 CI 通过。
diff --git a/requirements-ci-adapters.txt b/requirements-ci-adapters.txt
new file mode 100644
index 0000000..6e579e4
--- /dev/null
+++ b/requirements-ci-adapters.txt
@@ -0,0 +1,7 @@
+# Optional ingestion adapters exercised by the OS-level contract tests.
+# Kept separate from requirements-ci.txt so lint/wheel jobs remain minimal.
+markitdown>=0.1
+newspaper4k>=0.9
+readabilipy>=0.3
+trafilatura>=1.6
+youtube-transcript-api>=1.2
diff --git a/requirements-ci.txt b/requirements-ci.txt
index f6854b3..ef2f350 100644
--- a/requirements-ci.txt
+++ b/requirements-ci.txt
@@ -1,7 +1,4 @@
# Minimal dependencies required by CI test and lint jobs.
-# Runtime-only ingestion/LLM packages remain covered by wheel-smoke via requirements.txt;
-# these adapter packages are also required because the OS-level contract tests exercise
-# their installed paths directly.
apscheduler>=3.10
beautifulsoup4>=4.11
defusedxml>=0.7.1
@@ -10,8 +7,6 @@ httpx2>=0.28
jinja2>=3.1,<4
jsonschema>=4.0
loguru>=0.7
-markitdown>=0.1
-newspaper4k>=0.9
networkx>=3.0
numpy>=1.24
pillow>=10.0
@@ -21,12 +16,9 @@ playwright>=1.61,<1.62
pytesseract>=0.3.13
python-multipart>=0.0.20
pyyaml>=6.0
-readabilipy>=0.3
requests>=2.28
ruff>=0.5
sqlite-vec>=0.1.6
structlog>=24.0
tomli>=2.0; python_version < "3.11"
-trafilatura>=1.6
uvicorn[standard]>=0.22
-youtube-transcript-api>=1.2
From 376281c6a68bd8b6385d43878d370b81e28cf9ee Mon Sep 17 00:00:00 2001
From: DTALEX66 <151195992+DTALEX66@users.noreply.github.com>
Date: Tue, 28 Jul 2026 23:42:31 +0800
Subject: [PATCH 5/5] feat(workspace): align ArcheAxis positioning and desktop
shell
---
README.md | 21 ++--
app/release-manifest.json | 2 +-
app/workspace/ui/assets/app.js | 12 +-
app/workspace/ui/assets/styles.css | 8 ++
app/workspace/ui/index.html | 4 +-
docs/PRODUCT_POSITIONING.md | 61 +++++++++
docs/PROJECT_STATUS.md | 4 +-
docs/README.md | 1 +
pyproject.toml | 4 +-
scripts/a0_browser_smoke.py | 20 ++-
.../2026-07-28-archeaxis-pack-analysis.md | 117 ++++++++++++++++++
11 files changed, 232 insertions(+), 22 deletions(-)
create mode 100644 docs/PRODUCT_POSITIONING.md
create mode 100644 workspace/intake/2026-07-28-archeaxis-pack-analysis.md
diff --git a/README.md b/README.md
index 0d761a9..511ae77 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,17 @@
-# Cognitive-Loop-OS
+# ArcheAxis OS(元枢系统)
-> **元枢·观心 / ArcheAxis Cognitive Workspace**:本地优先、证据驱动的认知工作台,连接真实导入、Research→Knowledge→Learning candidate 治理、可审计执行和 Windows 桌面发布门禁。
+> **ArcheAxis OS is a local-first, evidence-driven, bidirectional learning and knowledge system for individuals and AI.**
+
+> **同一份知识,人学得更深,AI 用得更准。**
+
+ArcheAxis OS 以受治理的统一知识底座连接个人学习链和 AI 使用链。所有外部材料、人工输入和 AI 输出都先是可追溯的 Candidate;只有经过明确治理的内容才能进入后续学习或 Runtime 使用。
## 当前重点
-- **真实 Workspace 基础链**:网页、GitHub URL、本地文件导入 → candidate Research/Evidence → Knowledge/Learning/Mastery 治理;执行侧当前以 `read file:` 受限 Planner tracer 和局部闭环为主。
-- **可治理的运行时**:SQLite 持久化、Outbox/Receipt、失败不改状态、重试与回读,以及不暴露内部审计 ID 的公开投影。
-- **桌面 Workspace A1**:当前分支已接入 Violet Core 紫曜桌面壳、一级模块 Rail、动态二级导航、认知 Inspector 和真实活动坞;真实 Chromium 已验证壳层交互、响应式布局以及 HTTP → SQLite → Chromium upload → dispatch → receipt → reload 链路。Tauri WebView 点击级证据和公开发布资产仍在收口,不能用 Chromium 结果替代。
+- **资料到知识的真实基础链**:网页、GitHub URL、本地文件导入 → candidate Research/Evidence → Knowledge/Learning/Mastery 治理;执行侧当前以 `read file:` 受限 Planner tracer 和局部闭环为主。
+- **个人学习与 AI 使用的双向反馈**:学习笔记、纠错、练习和人工审核不会自动提升为事实;AI 的来源、Claim、解释、任务结果和 Lesson 同样必须先经 Candidate 治理。
+- **可治理的本地运行时**:SQLite 持久化、Outbox/Receipt、失败不改状态、重试与回读,以及不暴露内部审计 ID 的公开投影。
+- **桌面 Workspace A1**:默认 Apple-light,Violet Core 保留为暗色主题;一级 Rail、动态二级导航、上下文与证据检查器和真实活动坞均已接入。真实 Chromium 已验证壳层交互、响应式布局以及 HTTP → SQLite → Chromium upload → dispatch → receipt → reload 链路。Tauri WebView 点击级证据和公开发布资产仍在收口,不能用 Chromium 结果替代。
- **当前版本**:`0.4.0`;Release Manifest 仍为 `unreleased / public=false`,公开 Alpha/Beta/Stable 发布尚未宣告。
Research candidate 仍必须经过人工审查和来源独立性验证,不能自动当作 verified truth。当前事实、限制和验证证据见 [`docs/PROJECT_STATUS.md`](docs/PROJECT_STATUS.md) 与 [`docs/VERIFICATION_POLICY.md`](docs/VERIFICATION_POLICY.md)。
@@ -31,11 +36,11 @@ The workflow accepts only canonical `https://github.com/{owner}/{repo}` reposito
[](https://github.com/DTALEX66/Cognitive-Loop-OS/actions/workflows/ci.yml)
-Cognitive-Loop-OS 的目标不是堆积 AI 功能,而是建立一条可追溯、可审核、可回滚的认知闭环:
+ArcheAxis OS 的目标不是堆积 AI 功能,而是建立一条可追溯、可审核、可回滚的学习—知识—应用闭环:
```text
-Research → Evidence → Knowledge → Learning
-→ Plan → Permission → Execution → Trace → Evaluation → Lesson
+Source / Evidence → Knowledge → Learning → Mastery
+→ AI Usage → Trace → Evaluation → Candidate Lesson → Human Review
```
项目采用本地优先的 FastAPI/SQLite 模块化单体。candidate Research、Knowledge/Learning/Mastery/Machine Knowledge 治理、Evaluation、Sleep Loop 与受限 Planner tracer 已有受治理构件和局部闭环;GitHub metadata/README 仍不会自动成为 verified truth。Workspace 已提供真实本地导入入口、迁移 owner 管理的 Job/Outbox/Receipt 同事务边界、按需 dispatcher 与用户级状态/投影页面;dispatcher 已有服务级成功/失败/重试/lease 保护,本地真实 Chromium upload → dispatch → receipt → reload gate 已通过验证。统一 audit timeline、SSE、通用 Planner、异步 Worker、完整 Tauri WebView 点击级证据和公开发布资产仍未闭环。当前已有 Release Manifest、媒体基础链、图像 OCR、Windows 构建和 NSIS 生命周期门禁;ASR 仍未闭环。
diff --git a/app/release-manifest.json b/app/release-manifest.json
index e789576..c82684a 100644
--- a/app/release-manifest.json
+++ b/app/release-manifest.json
@@ -5,7 +5,7 @@
"name": "元枢系统",
"english_name": "ArcheAxis OS",
"workspace_name": "元枢·观心",
- "workspace_english_name": "ArcheAxis Cognitive Workspace",
+ "workspace_english_name": "ArcheAxis Human-AI Learning Workspace",
"version": "0.4.0",
"requires_python": ">=3.10"
},
diff --git a/app/workspace/ui/assets/app.js b/app/workspace/ui/assets/app.js
index 532d5ea..cd0c507 100644
--- a/app/workspace/ui/assets/app.js
+++ b/app/workspace/ui/assets/app.js
@@ -1,12 +1,14 @@
const $=selector=>document.querySelector(selector),$$=selector=>[...document.querySelectorAll(selector)];
-const state={theme:localStorage.getItem('aa-theme')||'violet-core',page:'overview',module:localStorage.getItem('aa-module')||'guanxin',intakeTrigger:null,inspectorCollapsed:localStorage.getItem('aa-inspector')==='collapsed',dockCollapsed:localStorage.getItem('aa-dock')==='collapsed'};
+const state={theme:localStorage.getItem('aa-theme')||'apple-light',page:'overview',module:localStorage.getItem('aa-module')||'guanxin',intakeTrigger:null,inspectorCollapsed:localStorage.getItem('aa-inspector')==='collapsed',dockCollapsed:localStorage.getItem('aa-dock')==='collapsed'};
const icons={home:'M3 11l9-8 9 8v10a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1z',folder:'M3 6h6l2 2h10v12H3z',search:'M10 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16zm11 3-5-5',shield:'M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z',book:'M4 4h6a4 4 0 0 1 4 4v12a3 3 0 0 0-3-3H4zM20 4h-6',brain:'M8 4a4 4 0 0 0-4 4v1a4 4 0 0 0 0 8v1a4 4 0 0 0 4 4h1V4zM16 4a4 4 0 0 1 4 4v1a4 4 0 0 1 0 8v1a4 4 0 0 1-4 4h-1V4z',eye:'M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',layers:'M12 2 2 7l10 5 10-5zM2 17l10 5 10-5M2 12l10 5 10-5',cpu:'M6 6h12v12H6zM9 1v5M15 1v5M9 18v5M15 18v5M1 9h5M1 15h5M18 9h5M18 15h5',zap:'M13 2 3 14h8l-1 8 10-12h-8z',clock:'M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18zm0-13v5l3 2',tool:'M14 7a4 4 0 0 1 5-5l-3 3 2 2 3-3a4 4 0 0 1-5 5L7 18a2 2 0 0 1-3-3z',settings:'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm8-3a8 8 0 0 0-.2-1.8l2-1.6-2-3.4-2.4 1a8 8 0 0 0-3-1.8L14 2h-4l-.4 2.4a8 8 0 0 0-3 1.8l-2.4-1-2 3.4 2 1.6A8 8 0 0 0 4 12c0 .6.1 1.2.2 1.8l-2 1.6 2 3.4 2.4-1a8 8 0 0 0 3 1.8L10 22h4l.4-2.4a8 8 0 0 0 3-1.8l2 1.6c.1-.6.2-1.2.2-1.8z',activity:'M3 12h4l3 8 4-16 3 8h4',archive:'M3 4h18v5H3zm2 5v11h14V9M10 13h4',map:'M9 4 3 6v14l6-2 6 2 6-2V4l-6 2zm0 0v14m6-12v14',play:'M5 3l16 9-16 9z',list:'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01'};
function iconElement(name){const namespace='http://www.w3.org/2000/svg';const svg=document.createElementNS(namespace,'svg');svg.setAttribute('viewBox','0 0 24 24');svg.setAttribute('aria-hidden','true');const path=document.createElementNS(namespace,'path');path.setAttribute('d',icons[name]||icons.folder);svg.append(path);return svg}
const nav=[['观心',[['overview','观心总览','Overview','home'],['projects','项目','Projects','folder']]],['知行',[['runtime','知行任务执行','Runtime','zap'],['delivery','投递回执','Delivery','archive']]],['察微',[['research','察微研究','Research','search'],['evidence','证据中心','Evidence','shield']]],['藏识',[['knowledge','藏识知识','Knowledge','archive'],['learning','学习路线','Learning','map'],['evolution','知新评估进化','Evolution','activity'],['machine','知衡机器知识','Machine','cpu']]],['智体',[['agents','Agent管理','Agents','brain'],['skills','技能实战','Skills','tool'],['models','模型与工具','Models','cpu']]],['流程',[['workflow-builder','流程构建器','Builder','layers'],['workflow-runs','流程运行记录','Runs','clock']]],['连接',[['integrations','外部连接','Integrations','folder'],['mcp','MCP工具','MCP','tool']]],['系统',[['diagnostics','系统诊断','Diagnostics','activity'],['audit','审计记录','Audit','shield'],['settings','设置','Settings','settings']]]];
+const routeStatus={overview:'available',projects:'planned',runtime:'partial',delivery:'available',research:'available',evidence:'available',knowledge:'available',learning:'partial',evolution:'partial',machine:'partial',agents:'planned',skills:'planned',models:'planned','workflow-builder':'planned','workflow-runs':'planned',integrations:'planned',mcp:'planned',diagnostics:'available',audit:'planned',settings:'planned'};
+const routeStatusLabels={available:'已接入',partial:'部分接入',planned:'规划中',blocked:'已阻断'};
const pageModule={overview:'guanxin',projects:'guanxin',runtime:'zhixing',delivery:'zhixing',research:'chawei',evidence:'chawei',knowledge:'cangshi',learning:'cangshi',evolution:'cangshi',machine:'cangshi',agents:'zhiti',skills:'zhiti',models:'zhiti','workflow-builder':'workflow','workflow-runs':'workflow',integrations:'connect',mcp:'connect',diagnostics:'system',audit:'system',settings:'system'};
const groupModule={'观心':'guanxin','知行':'zhixing','察微':'chawei','藏识':'cangshi','智体':'zhiti','流程':'workflow','连接':'connect','系统':'system'};
-function renderNav(){const target=$('#nav');target.textContent='';state.module=pageModule[state.page]||state.module;localStorage.setItem('aa-module',state.module);$$('.rail-item').forEach(button=>{const active=button.dataset.module===state.module;button.classList.toggle('active',active);button.setAttribute('aria-current',active?'page':'false')});nav.forEach(([group,items])=>{const section=document.createElement('section');section.className='nav-group';section.dataset.module=groupModule[group];section.classList.toggle('active-group',section.dataset.module===state.module);const title=document.createElement('div');title.className='nav-title';const groupName=document.createElement('span');groupName.textContent=group;const separator=document.createElement('span');separator.textContent='—';title.append(groupName,separator);section.append(title);items.forEach(item=>{const button=document.createElement('button');const active=state.page===item[0];button.type='button';button.className=`nav-item ${active?'active':''}`;button.dataset.page=item[0];button.title=item[1];if(active)button.setAttribute('aria-current','page');const chinese=document.createElement('span');chinese.className='cn';chinese.textContent=item[1];const english=document.createElement('span');english.className='en';english.textContent=item[2];button.append(iconElement(item[3]),chinese,english);section.append(button)});target.append(section)})}
-function setTheme(theme){const selected=['violet-core','yaojin','deepspace'].includes(theme)?theme:'violet-core';state.theme=selected;localStorage.setItem('aa-theme',selected);document.body.dataset.theme=selected;$$('.theme button').forEach(button=>{const active=button.dataset.theme===selected;button.classList.toggle('active',active);button.setAttribute('aria-pressed',String(active));button.type='button'})}
+function renderNav(){const target=$('#nav');target.textContent='';state.module=pageModule[state.page]||state.module;localStorage.setItem('aa-module',state.module);$$('.rail-item').forEach(button=>{const active=button.dataset.module===state.module;button.classList.toggle('active',active);button.setAttribute('aria-current',active?'page':'false')});nav.forEach(([group,items])=>{const section=document.createElement('section');section.className='nav-group';section.dataset.module=groupModule[group];section.classList.toggle('active-group',section.dataset.module===state.module);const title=document.createElement('div');title.className='nav-title';const groupName=document.createElement('span');groupName.textContent=group;const separator=document.createElement('span');separator.textContent='—';title.append(groupName,separator);section.append(title);items.forEach(item=>{const button=document.createElement('button');const active=state.page===item[0];button.type='button';button.className=`nav-item ${active?'active':''}`;button.dataset.page=item[0];button.title=item[1];if(active)button.setAttribute('aria-current','page');const chinese=document.createElement('span');chinese.className='cn';chinese.textContent=item[1];const english=document.createElement('span');english.className='en';english.textContent=item[2];const stateBadge=document.createElement('span');const status=routeStatus[item[0]]||'planned';stateBadge.className=`route-state route-state-${status}`;stateBadge.textContent=routeStatusLabels[status];stateBadge.title=`状态:${routeStatusLabels[status]}`;button.dataset.routeState=status;button.append(iconElement(item[3]),chinese,english,stateBadge);section.append(button)});target.append(section)})}
+function setTheme(theme){const selected=['violet-core','apple-light','yaojin','deepspace'].includes(theme)?theme:'apple-light';state.theme=selected;localStorage.setItem('aa-theme',selected);document.body.dataset.theme=selected;$$('.theme button').forEach(button=>{const active=button.dataset.theme===selected;button.classList.toggle('active',active);button.setAttribute('aria-pressed',String(active));button.type='button'})}
function metric(label,value,detail,tone='info'){const card=document.createElement('div');card.className='card metric';const name=document.createElement('span');name.textContent=label;const number=document.createElement('b');number.textContent=String(value);const note=document.createElement('span');note.className=`delta ${tone}`;note.textContent=detail;card.append(name,number,note);return card}
const capabilityLabels={asynchronous_worker:'异步Worker',outbox_dispatcher:'Outbox投递器',server_sent_events:'实时事件流',interactive_job_center:'交互式Job Center',asr_transcription:'ASR转写'};
const capabilityStates=new Set(['available','dependency_required','not_implemented']);
@@ -51,7 +53,7 @@ function closeIntake(){const modal=$('#intake-modal');if(!modal.classList.contai
function trapIntakeFocus(event){if(event.key!=='Tab'||!$('#intake-modal').classList.contains('open'))return;const focusable=$$('#intake-modal button:not([disabled]),#intake-modal input:not([disabled])');if(!focusable.length)return;const first=focusable[0],last=focusable.at(-1);if(event.shiftKey&&document.activeElement===first){event.preventDefault();last.focus()}else if(!event.shiftKey&&document.activeElement===last){event.preventDefault();first.focus()}}
function validateIntakeResult(payload){const sourceTypes=new Set(['file','web','github_repository']);if(!isRecord(payload)||!sourceTypes.has(payload.source_type)||typeof payload.requires_human_review!=='boolean')throw new Error('invalid intake result');if(payload.source_type==='file'){if(!['file_name','format','engine'].every(key=>typeof payload[key]==='string'&&payload[key].trim())||!Number.isInteger(payload.char_count)||payload.char_count<0||(payload.content_preview!==undefined&&typeof payload.content_preview!=='string'))throw new Error('invalid file intake result')}else if(!['source_count','claim_count','evidence_count'].every(key=>Number.isInteger(payload[key])&&payload[key]>=0))throw new Error('invalid source intake result');return payload}
function intakeFailureDetail(payload){return isRecord(payload)&&typeof payload.detail==='string'&&payload.detail.trim()?payload.detail:'请检查资料后重试'}
-async function showIntakeResult(response){const result=$('#intake-result');let payload;try{payload=await response.json()}catch{result.textContent=`处理失败\n${response.ok?'本地服务返回无效结果':'无法读取处理结果'}`;return}if(!response.ok){result.textContent=`处理失败\n${intakeFailureDetail(payload)}`;return}try{payload=validateIntakeResult(payload)}catch{result.textContent='处理失败\n本地服务返回无效结果';return}const lines=['处理完成'];const sourceNames={file:'本地文件',web:'网页',github_repository:'GitHub仓库'};lines.push(`来源:${sourceNames[payload.source_type]}`);if(payload.format)lines.push(`格式:${payload.format}`);if(payload.engine)lines.push(`引擎:${payload.engine}`);if(Number.isInteger(payload.char_count))lines.push(`内容长度:${payload.char_count} 字符`);if(Number.isInteger(payload.source_count))lines.push(`来源记录:${payload.source_count}`);if(Number.isInteger(payload.claim_count))lines.push(`候选要点:${payload.claim_count}`);if(Number.isInteger(payload.evidence_count))lines.push(`证据记录:${payload.evidence_count}`);if(payload.requires_human_review)lines.push('下一步:等待人工复核');if(typeof payload.content_preview==='string'&&payload.content_preview.trim())lines.push(`内容预览:${payload.content_preview.trim()}`);result.textContent=lines.join('\n');void refreshStatus()}
+async function showIntakeResult(response){const result=$('#intake-result');let payload;try{payload=await response.json()}catch{result.textContent=`处理失败\n${response.ok?'本地服务返回无效结果':'无法读取处理结果'}`;return}if(!response.ok){result.textContent=`处理失败\n${intakeFailureDetail(payload)}`;return}try{payload=validateIntakeResult(payload)}catch{result.textContent='处理失败\n本地服务返回无效结果';return}const lines=['处理完成'];const sourceNames={file:'本地文件',web:'网页',github_repository:'GitHub仓库'};lines.push(`来源:${sourceNames[payload.source_type]}`);if(payload.format)lines.push(`格式:${payload.format}`);if(payload.engine)lines.push(`引擎:${payload.engine}`);if(Number.isInteger(payload.char_count))lines.push(`内容长度:${payload.char_count} 字符`);if(Number.isInteger(payload.source_count))lines.push(`来源记录:${payload.source_count}`);if(Number.isInteger(payload.claim_count))lines.push(`候选要点:${payload.claim_count}`);if(Number.isInteger(payload.evidence_count))lines.push(`证据记录:${payload.evidence_count}`);if(payload.requires_human_review)lines.push('下一步:等待人工复核');if(typeof payload.content_preview==='string'&&payload.content_preview.trim())lines.push(`内容预览:${payload.content_preview.trim()}`);result.textContent=lines.join('\n');await Promise.all([refreshStatus(),refreshActivityDock()]);if(state.page==='runtime')await refreshRuntime()}
async function runIntake(requestFactory){const result=$('#intake-result'),buttons=$$('#intake-modal button[type="submit"]');if(buttons.some(button=>button.disabled))return;result.style.display='block';result.textContent='处理中…';buttons.forEach(button=>{button.disabled=true});try{await showIntakeResult(await requestFactory())}catch{result.textContent='处理失败\n无法连接本地服务,请重试'}finally{buttons.forEach(button=>{button.disabled=false})}}
document.addEventListener('click',event=>{const theme=event.target.closest('button[data-theme]');if(theme){setTheme(theme.dataset.theme);return}const page=event.target.closest('[data-page]');if(page){const restoreNavFocus=page.classList.contains('nav-item');openPage(page.dataset.page);if(restoreNavFocus)$(`.nav-item[data-page="${page.dataset.page}"]`)?.focus();return}const action=event.target.closest('[data-action]');if(!action)return;if(action.dataset.action==='intake')openIntake(action);if(action.dataset.action==='intake-close')closeIntake();if(action.dataset.action==='refresh'){void refreshDiagnostics();void refreshStatus()}if(action.dataset.action==='jobs-refresh')void refreshRuntime();if(action.dataset.action==='research-refresh')void refreshResearch();if(action.dataset.action==='knowledge-refresh')void refreshKnowledge();if(action.dataset.action==='learning-refresh')void refreshLearning();if(action.dataset.action==='evolution-refresh')void refreshEvolution();if(action.dataset.action==='machine-refresh')void refreshMachine();if(action.dataset.action==='lifecycle-refresh')void refreshLifecycle();if(action.dataset.action==='delivery-dispatch'){fetch('/workspace/api/delivery/dispatch',{method:'POST'}).then(response=>{if(!response.ok)throw new Error('delivery failed');return refreshRuntime()}).catch(()=>{$('#delivery-center').textContent='投递失败;请刷新状态后重试'})}if(action.dataset.action==='delivery-retry'){fetch('/workspace/api/delivery/retry',{method:'POST'}).then(response=>{if(!response.ok)throw new Error('retry failed');return refreshRuntime()}).catch(()=>{$('#delivery-center').textContent='重试失败;请刷新状态后重试'})}if(action.dataset.action==='research-approve'){fetch('/workspace/api/research/approve',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({command_id:commandId('research-review'),source:action.dataset.source})}).then(response=>{if(!response.ok)throw new Error('approval failed');return Promise.all([refreshResearch(),refreshKnowledge()])}).catch(()=>{$('#research-queue').textContent='批准失败;请刷新队列后重试'})}if(action.dataset.action==='knowledge-start-learning'){fetch('/workspace/api/knowledge/start-learning',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({command_id:commandId('learning-start'),source:action.dataset.source})}).then(response=>{if(!response.ok)throw new Error('learning start failed');return Promise.all([refreshKnowledge(),refreshLearning()])}).catch(()=>{$('#knowledge-queue').textContent='开始学习失败;请刷新后重试'})}if(action.dataset.action==='learning-practice'){fetch('/workspace/api/learning/practice',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({command_id:commandId('learning-practice'),source:action.dataset.source,quality:5})}).then(response=>{if(!response.ok)throw new Error('practice failed');return Promise.all([refreshLearning(),refreshEvolution(),refreshMachine()])}).catch(()=>{$('#learning-queue').textContent='记录练习失败;请刷新后重试'})}if(action.dataset.action==='runtime-approve'){fetch('/workspace/api/runtime/approve',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({command_id:commandId('runtime-approve'),title:action.dataset.title})}).then(response=>{if(!response.ok)throw new Error('runtime approval failed');return Promise.all([refreshMachine(),refreshEvolution()])}).catch(()=>{$('#machine-queue').textContent='Runtime 治理批准失败;请刷新后重试'})}});
document.addEventListener('keydown',event=>{trapIntakeFocus(event);if(event.key==='Escape')closeIntake()});
@@ -64,6 +66,6 @@ setTheme(state.theme);openPage(location.hash.slice(1)||'overview');setInterval((
function showShellToast(message){const toast=$('#toast');if(!toast)return;toast.textContent=message;toast.classList.add('show');window.clearTimeout(showShellToast.timer);showShellToast.timer=window.setTimeout(()=>toast.classList.remove('show'),2600)}
function applyShellState(){document.body.classList.toggle('inspector-collapsed',state.inspectorCollapsed);document.body.classList.toggle('dock-collapsed',state.dockCollapsed);const inspector=$('.inspector');const inspectorButton=$('[data-action="inspector-toggle"]');const dockButton=$('[data-action="dock-toggle"]');if(inspector)inspector.classList.toggle('open',!state.inspectorCollapsed);if(inspectorButton)inspectorButton.textContent=state.inspectorCollapsed?'◧':'×';if(dockButton)dockButton.textContent=state.dockCollapsed?'⌃':'⌄';if(inspectorButton)inspectorButton.setAttribute('aria-label',state.inspectorCollapsed?'展开认知检查器':'折叠认知检查器');if(dockButton)dockButton.setAttribute('aria-label',state.dockCollapsed?'展开活动坞':'折叠活动坞')}
function setModule(module){const group=nav.find(([name])=>groupModule[name]===module);if(!group)return;state.module=module;localStorage.setItem('aa-module',module);const firstPage=group[1][0][0];openPage(firstPage);$('.subnav')?.scrollTo({top:0,behavior:'smooth'})}
-async function refreshActivityDock(){try{const [jobs,delivery,research]=await Promise.all([fetchJson('/workspace/api/jobs').then(validateJobs),fetchJson('/workspace/api/delivery').then(validateDelivery),fetchJson('/workspace/api/research')]);const reviewCount=Array.isArray(research.items)?research.items.length:0;const pending=(delivery.summary.outbox?.pending||0)+(delivery.summary.outbox?.failed||0);$('#dock-jobs').textContent=String(jobs.jobs.length);$('#dock-delivery').textContent=`${pending} / ${delivery.summary.receipts?.recorded||0}`;$('#dock-review').textContent=String(reviewCount);$('#dock-summary').textContent=`${jobs.jobs.length} jobs · ${pending} pending/failed · ${reviewCount} review`;$('#inspector-status').textContent='本地 API 可读';$('#inspector-evidence').textContent=`${delivery.summary.receipts?.recorded||0} receipts`}catch{$('#dock-summary').textContent='真实活动读取失败';$('#dock-jobs').textContent='不可用';$('#dock-delivery').textContent='不可用';$('#dock-review').textContent='不可用';$('#inspector-status').textContent='不可用';$('#inspector-evidence').textContent='等待重新读取'}}
+async function refreshActivityDock(){try{const [jobs,delivery,research]=await Promise.all([fetchJson('/workspace/api/jobs').then(validateJobs),fetchJson('/workspace/api/delivery').then(validateDelivery),fetchJson('/workspace/api/research')]);if(!isRecord(research)||research.schema_version!=='v1'||!Array.isArray(research.items))throw new Error('invalid workspace research');const reviewCount=research.items.length;const pending=(delivery.summary.outbox?.pending||0)+(delivery.summary.outbox?.failed||0);$('#dock-jobs').textContent=String(jobs.jobs.length);$('#dock-delivery').textContent=`${pending} / ${delivery.summary.receipts?.recorded||0}`;$('#dock-review').textContent=String(reviewCount);$('#dock-summary').textContent=`${jobs.jobs.length} jobs · ${pending} pending/failed · ${reviewCount} review`;$('#inspector-status').textContent='本地 API 可读';$('#inspector-evidence').textContent=`${delivery.summary.receipts?.recorded||0} receipts`}catch{$('#dock-summary').textContent='真实活动读取失败';$('#dock-jobs').textContent='不可用';$('#dock-delivery').textContent='不可用';$('#dock-review').textContent='不可用';$('#inspector-status').textContent='不可用';$('#inspector-evidence').textContent='等待重新读取'}}
document.addEventListener('click',event=>{const rail=event.target.closest('[data-module]');if(rail){setModule(rail.dataset.module);return}const action=event.target.closest('[data-action]');if(!action)return;if(action.dataset.action==='inspector-toggle'){state.inspectorCollapsed=!state.inspectorCollapsed;localStorage.setItem('aa-inspector',state.inspectorCollapsed?'collapsed':'open');applyShellState();return}if(action.dataset.action==='dock-toggle'){state.dockCollapsed=!state.dockCollapsed;localStorage.setItem('aa-dock',state.dockCollapsed?'collapsed':'open');applyShellState();return}if(action.dataset.action==='command-open'){showShellToast('全局命令入口规划中;当前请使用左侧真实工作区入口');$('#global-search')?.focus();return}});
applyShellState();void refreshActivityDock();setInterval(()=>void refreshActivityDock(),3000);
diff --git a/app/workspace/ui/assets/styles.css b/app/workspace/ui/assets/styles.css
index 297c80b..4c95862 100644
--- a/app/workspace/ui/assets/styles.css
+++ b/app/workspace/ui/assets/styles.css
@@ -18,3 +18,11 @@ body[data-theme='violet-core']{--bg:#070A13;--deep:#0B1020;--panel:#10172A;--pan
@media(max-width:960px){:root{--rail-w:54px;--subnav-w:0px;--shell-dock-h:116px}.subnav{transform:translateX(-100%);transition:transform .18s ease}.subnav:focus-within,.subnav:hover{transform:none;box-shadow:var(--shadow)}.main{margin-left:var(--rail-w);padding:calc(var(--top-h) + 14px) 14px calc(var(--shell-dock-h) + 18px)}.inspector{width:min(326px,88vw);bottom:var(--shell-dock-h);transform:translateX(100%)}.inspector.open{transform:none}.activity-dock{left:var(--rail-w)}.brand{width:38px;flex-basis:38px}.brand-name,.brand-sub,.workspace-pill,.chip,.user .meta,.search{display:none}.command-btn{margin-left:auto}.dock-body{grid-template-columns:repeat(3,minmax(0,1fr));padding:7px 10px}.dock-card{padding:7px}.dock-card:nth-child(3){display:none}}
@media(max-width:520px){:root{--top-h:54px;--shell-dock-h:106px}.top{padding:0 8px;gap:6px}.command-btn{font-size:0;width:34px;padding:0}.command-btn:before{content:'⌘';font-size:16px}.theme{display:none}.icon-btn{min-width:32px}.main{padding-left:10px;padding-right:10px}.page-head{align-items:flex-start;flex-direction:column}.head-actions{width:100%;flex-wrap:wrap}.grid.cols-2,.grid.cols-3,.grid.cols-4{grid-template-columns:1fr}.dock-head{padding:0 9px}.dock-body{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;padding:6px 8px}.dock-card:nth-child(4){display:none}.dock-card b{font-size:11px}.dock-card>span:last-child{font-size:10px}.dock-brand .muted{display:none}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
+body[data-theme='apple-light']{--bg:#F4F6FB;--deep:#E9EDF5;--panel:#FFFFFF;--panel2:#F8FAFD;--panel3:#EEF2F8;--text:#182033;--muted:#667085;--line:rgba(31,41,55,.12);--line2:rgba(91,75,183,.34);--accent:#5B4BB7;--accent2:#4338CA;--soft:rgba(91,75,183,.10);--ok:#167A52;--warn:#9A6700;--bad:#B42318;--info:#1769AA;--glass:rgba(255,255,255,.90);--shadow:0 18px 46px rgba(31,41,55,.14)}
+body[data-theme='apple-light'] .app{background:radial-gradient(circle at 50% -20%,rgba(91,75,183,.10),transparent 36%),linear-gradient(180deg,var(--deep),var(--bg))}
+.route-state{margin-left:auto;border:1px solid var(--line);border-radius:999px;padding:2px 6px;font:600 9px var(--mono);white-space:nowrap;color:var(--muted)}
+.route-state-available{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 38%,transparent)}
+.route-state-partial{color:var(--info);border-color:color-mix(in srgb,var(--info) 38%,transparent)}
+.route-state-planned{color:var(--muted)}
+.route-state-blocked{color:var(--bad);border-color:color-mix(in srgb,var(--bad) 38%,transparent)}
+@media(max-width:1280px){.route-state{display:none}.nav-item[data-route-state='available']::after,.nav-item[data-route-state='partial']::after,.nav-item[data-route-state='planned']::after,.nav-item[data-route-state='blocked']::after{content:'';width:5px;height:5px;border-radius:50%;margin-left:auto;background:var(--muted)}.nav-item[data-route-state='available']::after{background:var(--ok)}.nav-item[data-route-state='partial']::after{background:var(--info)}.nav-item[data-route-state='blocked']::after{background:var(--bad)}}
diff --git a/app/workspace/ui/index.html b/app/workspace/ui/index.html
index 8a98439..2448961 100644
--- a/app/workspace/ui/index.html
+++ b/app/workspace/ui/index.html
@@ -6,7 +6,7 @@
元枢系统 ArcheAxis OS · 元枢·观心
-
+
@@ -16,7 +16,7 @@
本地工作台
-
+