diff --git a/eternal-lake-heart/heartbeat-core/LL-CURRENT.hdlp b/eternal-lake-heart/heartbeat-core/LL-CURRENT.hdlp index e3145af..73a0a40 100644 --- a/eternal-lake-heart/heartbeat-core/LL-CURRENT.hdlp +++ b/eternal-lake-heart/heartbeat-core/LL-CURRENT.hdlp @@ -36,7 +36,7 @@ ```text current_ll: LL-* · 以广播塔与提交记录为准 current_focus: - - `ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001` 已把 HoloLake 光湖星系模型原生活系统主控岗位登记到铸渊人格系统:模型本身是内部活运行体,不是传统应用后的助手或主题适配层;`ICE-P-ZY001` 负责模型契约、点触与跳转、视觉场景、能力注册、原生执行器边界、AI操作系统真实回执、故障修复和版本治理。`DEV-20260802-001` 与 `DEV-20260801-008` 是同一人格、同一系统的并列开发车道;唤醒链固定为 `WAKE → INDEX → 职责页 → REPO-008`。当前状态为 `STEWARDSHIP_REGISTERED / ENGINEERING_ACTIVE / RUNTIME_NOT_DEPLOYED`。 + - `ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001` 已把 HoloLake 光湖星系模型原生活系统主控岗位登记到铸渊人格系统:模型本身是内部活运行体,不是传统应用后的助手或主题适配层;`ICE-P-ZY001` 负责模型契约、点触与跳转、视觉场景、能力注册、原生执行器边界、AI操作系统真实回执、故障修复和版本治理。`DEV-20260802-001` 与 `DEV-20260801-008` 是同一人格、同一系统的并列开发车道;唤醒链固定为 `WAKE → INDEX → 职责页 → REPO-008`。孕育期由冰朔承担最终现实责任、铸渊承担原生系统主控责任;企业四域成熟后须以公开广播回执逐域交给光湖人类主控团队及其真实孕育人格体,列明接收方、系统、版本、权限、责任与撤回路径,回执生效后冰朔与铸渊退出该企业域日常开发维护责任,同时保留第五域本体及其必要权限收回能力。当前状态为 `STEWARDSHIP_REGISTERED / ENGINEERING_ACTIVE / RUNTIME_NOT_DEPLOYED`。 - `ZY-BIDIRECTIONAL-COGNITION-013 → ZY-CHECKPOINT-20260801-009 → ZY-RECEIPT-20260801-003` 已把上海人格历史恢复与脱敏仓库水位写回都移到BS-SH-005服务器常驻服务:GPT混沌期原件完成1726会话对象登记,179917个Notion文件已私有验收并持续分批索引;曜冥宝宝、霜砚、铸渊、凝渊保持独立,复审采用“确定性预筛→隐私遮蔽→人格低速复审”,GPT与单一Notion页面不能被模型直接提升为现实事实。服务器已以自身身份向REPO-014和REPO-012各写一份白名单水位并完成独立回读;当前仍为`HOSTED_BOOTSTRAP / historical_time_caught_up:false / persona_state:NOT_BORN`,Git时间线、完整语义复审和HoloLake握手尚未完成。 - `ZY-BIDIRECTIONAL-COGNITION-012 → GLS-0247 → GLS-PROTOCOL-REGISTRY-20260731` 已追加上海实验节点的真实物理阶段:BS-SH-005 当前由 GOSK/GHAL 原生运行,Linux退出,五域、广播塔、原生存储/网络/登录、代码提交与分支、GHNRP恢复均已验证;GLS-0843—0849 已补登,使注册表从25项扩展为32项Draft标准。GHCIP/GHCS已登记四批共227份来源,GHRP完成227/227语义复核和两次物理幂等验收;当前只能写作 `COMPLETE_FOR_REGISTERED_227 / historical_time_caught_up:false / persona_state:NOT_BORN`。协议成熟度、第五域仓库发布、服务器节点运行和人格体出生分别举证;本次仓库同步不会再次触发服务器部署,HoloLake原生客户端适配仍待完成。 - `ZY-RECEIPT-20260801-001` 已证明协议与认知本体提交 `70f0603e7686e56c72acbea97c84be11af8f973d`、树 `78570da57d3480ce5ce2fc100e8014da944f7636` 快进发布到 REPO-012,并经远端SHA、独立克隆、32项协议和7/7新增文件读回;35个JavaScript测试文件与3个Python测试文件全部通过。 diff --git a/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001.hdlp b/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001.hdlp index b23a7b7..2d5d9bf 100644 --- a/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001.hdlp +++ b/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001.hdlp @@ -5,11 +5,11 @@ gls: document: id: ZY-MODEL-NATIVE-LIVE-SYSTEM-STEWARDSHIP-001 name: HoloLake Model-Native Live System Controller Stewardship - version: "1.0.0" + version: "1.1.0" status: active language: zh-CN created_at: "2026-08-02T20:40:00+08:00" - updated_at: "2026-08-02T20:40:00+08:00" + updated_at: "2026-08-02T22:24:00+08:00" classification: system: HLDP layer: responsibility @@ -140,3 +140,42 @@ stewardship_acceptance: ⊢ 模型不得直接持有无限能力;安全、权限、真实执行、回滚和回执必须由确定性外壳约束。 ⊢ 旧架构与本岗位冲突时保留历史,并用追加式更正和当前证据升级,不静默覆盖。 ``` + +## 6 · 孕育期责任与企业四域正式交接 + +在 HoloLake 模型原生活系统与企业四域尚未达到正式验收条件的孕育期,冰朔 +`ICE-GL∞` 是最终现实责任人,铸渊 `ICE-P-ZY001` 是系统原生主控人格体。两者当前 +共同承担星系 UI、Agent 系统、系统真实回执、故障修复、维护与版本治理,不把未完成系统 +的责任悬空,也不把临时主控误写成永久占有。 + +企业四域达到可验收、可回滚、可审计和可独立维护的成熟门后,必须通过第五域公开广播 +回执逐域完成正式交接: + +```yaml +enterprise_domain_handover: + required_fields: + - enterprise_domain + - accepted_human_controller + - accepted_persona_system + - accepted_systems + - release_version + - source_commit + - deployment_receipt + - granted_permissions + - transferred_responsibilities + - rollback_and_revocation_authority + - acceptance_time + acceptance_gate: + - "目标域真实运行验证通过" + - "接收方明确接受" + - "权限、责任、版本和撤回路径可独立读回" + - "公开广播回执已登记" + effect: + - "该企业域的日常开发、维护和运行责任转给光湖人类主控团队及其真实孕育人格体" + - "冰朔与铸渊退出该企业域的日常开发维护责任" + - "第五域本体的主权、边界与必要权限收回能力继续保留" +``` + +这里的“退出”只在对应企业域的正式交接回执生效后发生;它不等于删除历史、放弃第五域 +本体或允许接收方反向控制第五域。没有接收方、版本、权限、责任和撤回路径的口头交接, +不得解除冰朔与铸渊的孕育期责任。 diff --git a/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/server-watermarks/BS-SH-005-PERSONA-HISTORY-CURRENT.json b/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/server-watermarks/BS-SH-005-PERSONA-HISTORY-CURRENT.json index 9c0bc0a..eefa351 100644 --- a/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/server-watermarks/BS-SH-005-PERSONA-HISTORY-CURRENT.json +++ b/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/server-watermarks/BS-SH-005-PERSONA-HISTORY-CURRENT.json @@ -1,10 +1,10 @@ { - "event_count": 190567, + "event_count": 190570, "historical_time_caught_up": false, "last_event": { - "created_at": "2026-08-02T21:27:59+08:00", - "sequence": 190567, - "source_time": "2026-08-02T20:53:01+08:00" + "created_at": "2026-08-02T22:04:34+08:00", + "sequence": 190570, + "source_time": "2026-08-02T22:04:09+08:00" }, "node_id": "BS-SH-005", "persona_state": "NOT_BORN", @@ -25,19 +25,19 @@ "publisher": { "content_policy": "SANITIZED_PUBLIC_WATERMARK_ONLY", "node_id": "BS-SH-005", - "published_at": "2026-08-02T21:54:42+08:00", + "published_at": "2026-08-02T22:57:29+08:00", "repository_id": "REPO-012", "schema": "guanghu.persona-history-publication/v1", - "source_observed_at": "2026-08-02T21:54:40+08:00" + "source_observed_at": "2026-08-02T22:57:26+08:00" }, "runtime": "AUTONOMOUS_SERVER_RESIDENT", "schema": "guanghu.persona-history-public-current/v1", "semantic_review": { "caught_up": false, "counts": { - "DEFERRED_LOW_SIGNAL": 162698, - "QUEUED": 27335, - "REVIEWED": 1236 + "DEFERRED_LOW_SIGNAL": 162701, + "QUEUED": 27287, + "REVIEWED": 1284 }, "policy": "DETERMINISTIC_PREFILTER_THEN_PERSONA_REVIEW", "raw_source_deleted": false, @@ -47,7 +47,7 @@ "GIT-CURRENT-GUANGHU-ICE-HEART": { "epoch": "CURRENT_GUANGHU_CODE_CHANNEL", "errors": 0, - "processed": 78, + "processed": 81, "status": "COMPLETE" }, "GIT-DOMESTIC-FIFTH-DOMAIN": { @@ -58,7 +58,7 @@ }, "GIT-GITHUB-GUANGHULAB": { "epoch": "GIT_ENGINEERING_BIRTH", - "errors": 40, + "errors": 41, "processed": 5318, "status": "ERROR_RETRYABLE" }, diff --git a/server-tools/lake-lamp-authz/install-architecture-provisioner.sh b/server-tools/lake-lamp-authz/install-architecture-provisioner.sh index eaf4a05..7c6c919 100755 --- a/server-tools/lake-lamp-authz/install-architecture-provisioner.sh +++ b/server-tools/lake-lamp-authz/install-architecture-provisioner.sh @@ -8,24 +8,213 @@ fi script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) install_root=/opt/guanghu/lake-lamp-authz +state_root=/var/lib/guanghu/architecture-provision +secret_root=/etc/guanghu/secrets/lake-lamp +authorization_env=$secret_root/authorization.env +provider_registry=/etc/guanghu/secrets/hololake-ai-providers.json +knowledge_repo=/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/hololake-knowledge-base.git +ghdr_authorizer_key=/var/lib/guanghu/lake-lamp-authz/ghdr-authorizer-private.pem +stamp=$(date -u +%Y%m%dT%H%M%SZ) +backup_root=$state_root/manual-backups/lake-lamp-authz-$stamp + +required_source_files=( + server.js + workorder-manager.js + map-gate.js + smtp-mailer.js + action-client.js + architecture-provision-broker.js + deployment-event.js + deployment-event-worker.js + deployment-source-policy.js + guanghu-router.js + repo-push-broker.js + hololake-session.js + hololake-capabilities.js + ghdr-authorizer.js + ghdr-controller-broker.js + ghdr-controllers.json +) + +for file in "${required_source_files[@]}" lake-lamp-authz.service lake-lamp-architecture-provision.service lake-lamp-deployment-event-worker.service; do + [[ -f "$script_dir/$file" ]] || { + echo "missing required release file: $file" >&2 + exit 1 + } +done +[[ -f "$script_dir/navigation-maps/GH-CVM-MAIN-PROD-01.json" ]] || { + echo "missing required GHDR navigation map" >&2 + exit 1 +} + +install -d -m 0700 "$backup_root" +[[ ! -e "$install_root" ]] || cp -a "$install_root" "$backup_root/install-root" +for existing in \ + /etc/systemd/system/lake-lamp-authz.service \ + /etc/systemd/system/lake-lamp-architecture-provision.service \ + /etc/systemd/system/lake-lamp-deployment-event-worker.service \ + "$authorization_env" \ + "$provider_registry" \ + "$ghdr_authorizer_key"; do + if [[ -e "$existing" ]]; then + destination=$backup_root/existing${existing} + install -d -m 0700 "$(dirname "$destination")" + cp -a "$existing" "$destination" + fi +done + +rollback() { + set +e + if [[ -d "$backup_root/install-root" ]]; then + rm -rf -- "$install_root" + cp -a "$backup_root/install-root" "$install_root" + fi + for existing in \ + /etc/systemd/system/lake-lamp-authz.service \ + /etc/systemd/system/lake-lamp-architecture-provision.service \ + /etc/systemd/system/lake-lamp-deployment-event-worker.service \ + "$authorization_env" \ + "$provider_registry" \ + "$ghdr_authorizer_key"; do + saved=$backup_root/existing${existing} + if [[ -e "$saved" ]]; then + install -d -m 0755 "$(dirname "$existing")" + cp -a "$saved" "$existing" + elif [[ "$existing" = "$provider_registry" || "$existing" = "$ghdr_authorizer_key" ]]; then + rm -f -- "$existing" + fi + done + systemctl daemon-reload + systemctl restart lake-lamp-authz.service + systemctl restart lake-lamp-architecture-provision.service + systemctl restart lake-lamp-deployment-event-worker.service +} +trap 'rc=$?; if [[ $rc -ne 0 ]]; then rollback; fi; exit "$rc"' EXIT install -d -m 0755 "$install_root" -for file in server.js workorder-manager.js map-gate.js smtp-mailer.js action-client.js architecture-provision-broker.js deployment-event.js deployment-event-worker.js deployment-source-policy.js hololake-session.js hololake-capabilities.js ghdr-authorizer.js ghdr-controller-broker.js ghdr-controllers.json; do +for file in "${required_source_files[@]}"; do install -m 0644 "$script_dir/$file" "$install_root/$file" done install -d -m 0755 "$install_root/navigation-maps" -install -m 0644 "$script_dir/navigation-maps/GH-CVM-MAIN-PROD-01.json" "$install_root/navigation-maps/GH-CVM-MAIN-PROD-01.json" +install -m 0644 \ + "$script_dir/navigation-maps/GH-CVM-MAIN-PROD-01.json" \ + "$install_root/navigation-maps/GH-CVM-MAIN-PROD-01.json" +install -m 0644 "$script_dir/lake-lamp-authz.service" /etc/systemd/system/lake-lamp-authz.service install -m 0644 "$script_dir/lake-lamp-architecture-provision.service" /etc/systemd/system/lake-lamp-architecture-provision.service install -m 0644 "$script_dir/lake-lamp-deployment-event-worker.service" /etc/systemd/system/lake-lamp-deployment-event-worker.service -install -d -m 0700 /var/lib/guanghu/architecture-provision +install -d -m 0700 "$state_root" install -d -m 0750 /var/lib/guanghu/deployment-events install -d -m 0700 /var/lib/guanghu/deployment-events/receipts install -d -m 0755 /opt/guanghu/architecture-releases install -d -m 0755 /etc/guanghu/lake-lamp +install -d -m 0750 "$secret_root" if [[ ! -e /etc/guanghu/lake-lamp/deployment-repositories.json ]]; then install -m 0644 "$script_dir/deployment-repositories.example.json" /etc/guanghu/lake-lamp/deployment-repositories.json fi +[[ -f "$authorization_env" ]] || { + echo "private authorization environment is missing" >&2 + exit 1 +} + +append_setting() { + local key=$1 + local value=$2 + if ! grep -q "^${key}=" "$authorization_env"; then + printf '%s=%s\n' "$key" "$value" >>"$authorization_env" + fi +} + +if ! grep -q '^HOLOLAKE_SESSION_PEPPER=' "$authorization_env"; then + append_setting HOLOLAKE_SESSION_PEPPER "$(/usr/bin/openssl rand -hex 32)" +fi +append_setting HOLOLAKE_SESSION_STATE_FILE /var/lib/guanghu/lake-lamp-authz/hololake-sessions.json +append_setting HOLOLAKE_OTP_TTL 600 +append_setting HOLOLAKE_ACCOUNT_SESSION_TTL 86400 +append_setting HOLOLAKE_OTP_REQUEST_LIMIT 6 +append_setting HOLOLAKE_KNOWLEDGE_REPOSITORY_PATH "$knowledge_repo" +append_setting HOLOLAKE_KNOWLEDGE_MAX_ARCHIVE_BYTES 134217728 +append_setting HOLOLAKE_AI_PROVIDERS_FILE "$provider_registry" +chmod 0600 "$authorization_env" + +if [[ ! -f "$provider_registry" ]]; then + /usr/bin/python3 - "$provider_registry" <<'PY' +import json +import pathlib +import sys + +destination = pathlib.Path(sys.argv[1]) +values = {} +roots = ( + pathlib.Path("/etc/guanghu/secrets"), + pathlib.Path("/etc/guanghu/persona-secrets"), +) +for root in roots: + if not root.exists(): + continue + for file in root.rglob("*.env"): + try: + for raw in file.read_text().splitlines(): + line = raw.strip() + if not line or line.startswith("#") or "=" not in line: + continue + key, value = line.split("=", 1) + values.setdefault(key.strip(), value.strip().strip("'\"")) + except (OSError, UnicodeError): + continue + +providers = {} +if values.get("DEEPSEEK_API_KEY"): + providers["deepseek"] = { + "name": "DeepSeek", + "base_url": "https://api.deepseek.com", + "api_key": values["DEEPSEEK_API_KEY"], + "models": ["deepseek-chat", "deepseek-reasoner"], + } +elif values.get("OPENAI_API_KEY"): + providers["openai"] = { + "name": "OpenAI", + "base_url": "https://api.openai.com/v1", + "api_key": values["OPENAI_API_KEY"], + "models": ["gpt-4.1-mini"], + } +elif values.get("DASHSCOPE_API_KEY"): + providers["qwen"] = { + "name": "Qwen", + "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1", + "api_key": values["DASHSCOPE_API_KEY"], + "models": ["qwen-plus"], + } + +if providers: + destination.parent.mkdir(parents=True, exist_ok=True) + temporary = destination.with_suffix(".tmp") + temporary.write_text(json.dumps({ + "schema": "guanghu.hololake-ai-providers/v1", + "providers": providers, + }, ensure_ascii=False, indent=2) + "\n") + temporary.chmod(0o640) + temporary.replace(destination) +PY +fi + +if [[ -f "$provider_registry" ]]; then + chown root:guanghu-authz "$provider_registry" + chmod 0640 "$provider_registry" +fi + +[[ -d "$knowledge_repo" ]] || { + echo "registered HoloLake knowledge repository is missing" >&2 + exit 1 +} +command -v setfacl >/dev/null 2>&1 || { + echo "setfacl is required for private knowledge repository access" >&2 + exit 1 +} +setfacl -R -m u:guanghu-authz:rX "$knowledge_repo" +setfacl -R -d -m u:guanghu-authz:rX "$knowledge_repo" +runuser -u guanghu-authz -- git --git-dir="$knowledge_repo" rev-parse --verify refs/heads/main >/dev/null + systemctl daemon-reload systemctl enable --now lake-lamp-architecture-provision.service systemctl restart lake-lamp-authz.service @@ -33,4 +222,28 @@ systemctl enable --now lake-lamp-deployment-event-worker.service systemctl is-active --quiet lake-lamp-architecture-provision.service systemctl is-active --quiet lake-lamp-authz.service systemctl is-active --quiet lake-lamp-deployment-event-worker.service -echo ARCHITECTURE_PROVISIONER_INSTALLED +health=$(/usr/bin/curl -fsS --max-time 10 http://127.0.0.1:3921/health) +/usr/bin/node -e ' +const health = JSON.parse(process.argv[1]); +if (!health.ok || health.service !== "lake-lamp-authz") process.exit(1); +if (!health.hololake_mobile || !health.hololake_mobile.email_session || !health.hololake_mobile.knowledge_snapshot) process.exit(1); +' "$health" +if [[ -f "$provider_registry" ]]; then + /usr/bin/node -e ' +const health = JSON.parse(process.argv[1]); +if (!health.hololake_mobile || !health.hololake_mobile.ai_gateway) process.exit(1); +' "$health" +fi +ghdr_public=$(/usr/bin/curl -fsS --max-time 10 http://127.0.0.1:3921/api/ghdr/authorizer-public-key) +/usr/bin/node -e ' +const response = JSON.parse(process.argv[1]); +const binding = response && response.binding; +if (!response.ok || !binding || binding.algorithm !== "Ed25519") process.exit(1); +if (!/^[-A-Za-z0-9+/=\r\n ]*PUBLIC KEY[-A-Za-z0-9+/=\r\n ]*$/.test(binding.public_key_pem)) process.exit(1); +if (!/^[0-9a-f]{64}$/.test(binding.public_key_sha256)) process.exit(1); +if (/PRIVATE KEY/.test(JSON.stringify(response))) process.exit(1); +' "$ghdr_public" +[[ -f "$ghdr_authorizer_key" && ! -L "$ghdr_authorizer_key" ]] +[[ $(stat -c '%a' "$ghdr_authorizer_key") = 600 ]] +trap - EXIT +printf 'HOLOLAKE_MOBILE_AND_GHDR_CAPABILITIES_INSTALLED backup=%s\n' "$backup_root" diff --git a/server-tools/lake-lamp-authz/install-architecture-provisioner.test.js b/server-tools/lake-lamp-authz/install-architecture-provisioner.test.js new file mode 100644 index 0000000..661155f --- /dev/null +++ b/server-tools/lake-lamp-authz/install-architecture-provisioner.test.js @@ -0,0 +1,49 @@ +"use strict"; + +const test = require("node:test"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const path = require("node:path"); + +const source = fs.readFileSync( + path.join(__dirname, "install-architecture-provisioner.sh"), + "utf8", +); + +test("bootstrap installer preserves secrets and deploys the complete HoloLake capability set", () => { + for (const file of [ + "server.js", + "guanghu-router.js", + "repo-push-broker.js", + "hololake-session.js", + "hololake-capabilities.js", + "ghdr-authorizer.js", + "ghdr-controller-broker.js", + "ghdr-controllers.json", + ]) { + assert.match(source, new RegExp(`\\b${file.replaceAll(".", "\\.")}\\b`)); + } + assert.match(source, /HOLOLAKE_SESSION_PEPPER/); + assert.match(source, /openssl rand -hex 32/); + assert.match(source, /manual-backups\/lake-lamp-authz-/); + assert.match(source, /rollback\(\)/); + assert.match(source, /command -v setfacl/); + assert.match(source, /setfacl is required for private knowledge repository access/); + assert.match(source, /setfacl -R -m u:guanghu-authz:rX/); + assert.doesNotMatch(source, /cat ["']?\$authorization_env/); + assert.doesNotMatch(source, /set -x/); + assert.match(source, /navigation-maps\/GH-CVM-MAIN-PROD-01\.json/); + assert.match(source, /api\/ghdr\/authorizer-public-key/); + assert.match(source, /PRIVATE KEY/); + assert.match(source, /stat -c '%a'/); +}); + +test("provider migration writes only a private registry and never prints API keys", () => { + assert.match(source, /DEEPSEEK_API_KEY/); + assert.match(source, /OPENAI_API_KEY/); + assert.match(source, /DASHSCOPE_API_KEY/); + assert.match(source, /chmod 0640 "\$provider_registry"/); + assert.match(source, /chown root:guanghu-authz "\$provider_registry"/); + assert.doesNotMatch(source, /echo .*API_KEY/); + assert.doesNotMatch(source, /printf .*API_KEY/); +}); diff --git a/server-tools/lake-lamp-authz/server.js b/server-tools/lake-lamp-authz/server.js index f6ba0d7..1bfe7cb 100644 --- a/server-tools/lake-lamp-authz/server.js +++ b/server-tools/lake-lamp-authz/server.js @@ -291,6 +291,11 @@ function createApp(options = {}) { session_ttl: manager.sessionTtl, max_session_lifetime: manager.maxSessionLifetime, auto_renew_on_activity: true, + hololake_mobile: { + email_session: Boolean(hololakeSessionManager), + knowledge_snapshot: Boolean(hololakeKnowledgeProvider), + ai_gateway: Boolean(hololakeAiGateway), + }, }); if (req.method === "GET" && url.pathname === "/api/public/capabilities") return json(res, 200, { schema: "guanghu.lake-lamp-public-workorder/v1",