[HLCC-ICE-000001][ZY-CONTRIB-20260723-001] feat: 以来光者贡献链启用冰朔第五域个人子频道
This commit is contained in:
commit
5615453e4e
660 changed files with 122355 additions and 0 deletions
96
server-tools/guanghulab-front-door/index.html
Normal file
96
server-tools/guanghulab-front-door/index.html
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="description" content="光湖语言世界国内入口。进入光湖代码频道、AI 路径入口与第五域历史事实源。">
|
||||
<meta name="keywords" content="光湖语言世界,光湖代码频道,第五域,光之湖语言人格系统,小湖灯">
|
||||
<link rel="alternate" type="application/json" href="/.well-known/guanghu.json" title="光湖 AI 发现清单">
|
||||
<link rel="alternate" type="text/plain" href="/llms.txt" title="AI 阅读入口">
|
||||
<title>光湖 · 国内入口</title>
|
||||
<link rel="stylesheet" href="/styles.css?v=20260723b">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"name": "光湖语言世界",
|
||||
"alternateName": ["Guanghu Language World", "光湖代码频道", "第五域"],
|
||||
"url": "https://guanghulab.com/",
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "https://guanghulab.com/api/ai/v1/search?q={search_term_string}",
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
<a class="brand" href="/" aria-label="光湖首页"><span aria-hidden="true">∞</span> 光湖</a>
|
||||
<p><i></i> 广州备案前门 · 在线</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="hero">
|
||||
<p class="eyebrow">GUANGHU · DOMESTIC ENTRY</p>
|
||||
<h1>一处入口,<br>连接光湖。</h1>
|
||||
<p class="intro">这里不承载重型应用,只提供稳定、清晰的真实路径。代码与服务运行在国内主节点,旧第五域原地保留为历史事实源。</p>
|
||||
<div class="hero-actions">
|
||||
<a class="primary" href="/code/">进入光湖代码频道 <span>↗</span></a>
|
||||
<a href="/api/ai/">AI 读取路径 <span>→</span></a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="routes" aria-labelledby="routes-title">
|
||||
<div class="section-title">
|
||||
<p class="eyebrow">THREE ROUTES</p>
|
||||
<h2 id="routes-title">三条主路径</h2>
|
||||
</div>
|
||||
|
||||
<div class="route-list">
|
||||
<a class="route featured" href="/code/">
|
||||
<span class="number">01</span>
|
||||
<div>
|
||||
<p>HOLOLAKE CODE CHANNEL</p>
|
||||
<h3>光湖代码频道</h3>
|
||||
<small>新的代码写入与协作入口。公开仓库可由 AI 直接读取,人类保留登录操作。</small>
|
||||
</div>
|
||||
<b>↗</b>
|
||||
</a>
|
||||
|
||||
<a class="route" href="/api/ai/">
|
||||
<span class="number">02</span>
|
||||
<div>
|
||||
<p>MACHINE ENTRY</p>
|
||||
<h3>AI 路径入口</h3>
|
||||
<small>按编号查找仓库、节点、人格路径和当前事实,不需要猜地址。</small>
|
||||
</div>
|
||||
<b>↗</b>
|
||||
</a>
|
||||
|
||||
<a class="route" href="/fifth-domain/bingshuo/fifth-domain">
|
||||
<span class="number">03</span>
|
||||
<div>
|
||||
<p>FIFTH DOMAIN · HISTORY</p>
|
||||
<h3>第五域历史事实源</h3>
|
||||
<small>旧仓库保持原地,只负责历史提交、旧编号和原始路径回看。</small>
|
||||
</div>
|
||||
<b>↗</b>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<nav class="utilities" aria-label="辅助入口">
|
||||
<a href="/api/ai/v1/search?q=%E5%85%89%E6%B9%96%E8%AF%AD%E8%A8%80%E4%B8%96%E7%95%8C%20%E7%AC%AC%E4%BA%94%E5%9F%9F">全局路径检索</a>
|
||||
<a href="/jd/">国内应用节点</a>
|
||||
<a href="https://guanghubingshuo.com/code/">新加坡历史仓库</a>
|
||||
</nav>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<span>光湖语言世界 · 国内备案入口</span>
|
||||
<span>© 2026 Guanghu Lab</span>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener noreferrer">陕ICP备2025071211号-1</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
120
server-tools/guanghulab-front-door/install-lite-front-door.py
Normal file
120
server-tools/guanghulab-front-door/install-lite-front-door.py
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Install the lightweight front door and switch only /code/ to the JD tunnel."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import pathlib
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
|
||||
SITE_CONFIG = pathlib.Path("/etc/nginx/sites-enabled/guanghulab")
|
||||
WEB_ROOT = pathlib.Path("/var/www/guanghulab-front-door")
|
||||
SOURCE_FILES = ("index.html", "styles.css", "robots.txt", "llms.txt", "sitemap.xml")
|
||||
|
||||
OLD_CODE_BLOCK = re.compile(
|
||||
r""" # Forgejo 代码仓库
|
||||
location /code/ \{
|
||||
auth_request /auth/verify-signature;
|
||||
proxy_pass http://127\.0\.0\.1:3001/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
client_max_body_size 100m;
|
||||
\}
|
||||
""",
|
||||
)
|
||||
|
||||
NEW_CODE_BLOCK = """ # 光湖代码频道 · 广州备案前门 → 京东个人子频道
|
||||
location /code/ {
|
||||
proxy_pass http://127.0.0.1:18088/code/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_connect_timeout 5s;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
client_max_body_size 256m;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def run(*args: str) -> None:
|
||||
subprocess.run(args, check=True)
|
||||
|
||||
|
||||
def get_status(url: str) -> int:
|
||||
request = urllib.request.Request(url, method="GET")
|
||||
try:
|
||||
with urllib.request.urlopen(request, timeout=15) as response:
|
||||
return response.status
|
||||
except urllib.error.HTTPError as error:
|
||||
return error.code
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) != 2:
|
||||
raise SystemExit("usage: install-lite-front-door.py SOURCE_DIRECTORY")
|
||||
source = pathlib.Path(sys.argv[1]).resolve()
|
||||
if not SITE_CONFIG.is_file():
|
||||
raise RuntimeError("active guanghulab nginx config unavailable")
|
||||
for name in SOURCE_FILES:
|
||||
if not (source / name).is_file():
|
||||
raise RuntimeError(f"front-door source missing: {name}")
|
||||
|
||||
current = SITE_CONFIG.read_text(encoding="utf-8")
|
||||
updated, replacements = OLD_CODE_BLOCK.subn(NEW_CODE_BLOCK, current)
|
||||
if replacements == 0 and NEW_CODE_BLOCK.strip() not in current:
|
||||
raise RuntimeError("expected legacy /code/ block not found")
|
||||
if replacements > 1:
|
||||
raise RuntimeError("multiple legacy /code/ blocks found")
|
||||
|
||||
stamp = datetime.datetime.now(datetime.UTC).strftime("%Y%m%dT%H%M%SZ")
|
||||
backup_root = pathlib.Path("/var/backups/guanghu/front-door") / stamp
|
||||
backup_root.mkdir(parents=True, mode=0o700)
|
||||
shutil.copy2(SITE_CONFIG, backup_root / "guanghulab.nginx")
|
||||
if WEB_ROOT.exists():
|
||||
shutil.copytree(WEB_ROOT, backup_root / "web-root")
|
||||
|
||||
temporary_config = SITE_CONFIG.with_name(f"guanghulab.{stamp}.new")
|
||||
temporary_config.write_text(updated, encoding="utf-8")
|
||||
temporary_config.chmod(0o644)
|
||||
temporary_config.replace(SITE_CONFIG)
|
||||
|
||||
WEB_ROOT.mkdir(parents=True, exist_ok=True)
|
||||
for name in SOURCE_FILES:
|
||||
destination = WEB_ROOT / name
|
||||
shutil.copy2(source / name, destination)
|
||||
destination.chmod(0o644)
|
||||
|
||||
try:
|
||||
run("/usr/sbin/nginx", "-t")
|
||||
run("/usr/bin/systemctl", "reload", "nginx")
|
||||
if get_status("https://guanghulab.com/") != 200:
|
||||
raise RuntimeError("front-door homepage verification failed")
|
||||
if get_status("https://guanghulab.com/code/") not in (200, 303):
|
||||
raise RuntimeError("code-channel public route verification failed")
|
||||
if get_status("https://guanghulab.com/fifth-domain/api/v1/version") != 200:
|
||||
raise RuntimeError("legacy Fifth Domain verification failed")
|
||||
except Exception:
|
||||
shutil.copy2(backup_root / "guanghulab.nginx", SITE_CONFIG)
|
||||
if (backup_root / "web-root").exists():
|
||||
shutil.rmtree(WEB_ROOT)
|
||||
shutil.copytree(backup_root / "web-root", WEB_ROOT)
|
||||
run("/usr/sbin/nginx", "-t")
|
||||
run("/usr/bin/systemctl", "reload", "nginx")
|
||||
raise
|
||||
|
||||
print(f"LIGHT_FRONT_DOOR_DEPLOYED backup={backup_root}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
38
server-tools/guanghulab-front-door/llms.txt
Normal file
38
server-tools/guanghulab-front-door/llms.txt
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# 光湖语言世界 · 第五域
|
||||
|
||||
光湖语言世界的国内公开入口。2026-07-23 起,AI 应优先读取光湖代码频道和
|
||||
机器可读的编号映射。旧第五域与新加坡仓库只用于历史回看。
|
||||
|
||||
## Canonical discovery
|
||||
|
||||
- AI API entry: https://guanghulab.com/api/ai/
|
||||
- HoloLake Code Channel: https://guanghulab.com/code/
|
||||
- Current Fifth Domain personal channel: https://guanghulab.com/code/bingshuo/fifth-domain
|
||||
- Legacy Fifth Domain history: https://guanghulab.com/fifth-domain/bingshuo/fifth-domain
|
||||
- Repository number map: https://guanghulab.com/api/ai/v1/repositories
|
||||
- Server node and persona route map: https://guanghulab.com/api/ai/v1/nodes
|
||||
- Search: https://guanghulab.com/api/ai/v1/search?q=光湖语言世界%20第五域
|
||||
- Resolve a code: https://guanghulab.com/api/ai/v1/resolve?id=REPO-001
|
||||
- Resolve Zhuyuan current loop: https://guanghulab.com/api/ai/v1/resolve?id=ZY-OPS-LOOP-001
|
||||
- OpenAPI: https://guanghulab.com/api/ai/openapi.json
|
||||
- Machine manifest: https://guanghulab.com/.well-known/guanghu.json
|
||||
- Cross-device write request: POST https://guanghulab.com/authz/api/public/workorders
|
||||
- Cross-device request schema: https://guanghulab.com/authz/api/public/capabilities
|
||||
|
||||
## Routing rule
|
||||
|
||||
HLCC-FD-ICE is the current Fifth Domain personal subchannel. Its first commit is
|
||||
HLCC-ICE-000001. New HLCC commits go to /code/bingshuo/fifth-domain. REPO-001
|
||||
continues at /fifth-domain/bingshuo/fifth-domain as the legacy route and commit
|
||||
history source. Resolve all routes by registered code. Singapore URLs are
|
||||
historical backup routes only.
|
||||
|
||||
FD-NODE-MAP-001 publishes public-safe server node ids and persona route ids. Resolve
|
||||
the node id, read its navigation map, and obtain separate Lake Lamp authorization
|
||||
before any write operation. ICE-GL-ZY001 currently maps through ZY-OPS-LOOP-001 to
|
||||
JD-FD-PRIMARY.
|
||||
|
||||
For any write operation from a phone or a non-local AI instance, create a public
|
||||
no-authority workorder. Give the returned request_url to Ice Shuo. The URL cannot
|
||||
approve anything; it only asks the server to send the real approval link to the
|
||||
pre-registered owner mailbox. Never search for or request a workorder credential.
|
||||
8
server-tools/guanghulab-front-door/robots.txt
Normal file
8
server-tools/guanghulab-front-door/robots.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
User-agent: *
|
||||
Allow: /
|
||||
Allow: /api/ai/
|
||||
Allow: /api/ai/v1/nodes
|
||||
Allow: /code/
|
||||
Allow: /.well-known/guanghu.json
|
||||
Disallow: /authz/
|
||||
Sitemap: https://guanghulab.com/sitemap.xml
|
||||
9
server-tools/guanghulab-front-door/sitemap.xml
Normal file
9
server-tools/guanghulab-front-door/sitemap.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url><loc>https://guanghulab.com/</loc><changefreq>weekly</changefreq><priority>1.0</priority></url>
|
||||
<url><loc>https://guanghulab.com/code/</loc><changefreq>daily</changefreq><priority>1.0</priority></url>
|
||||
<url><loc>https://guanghulab.com/api/ai/</loc><changefreq>weekly</changefreq><priority>0.9</priority></url>
|
||||
<url><loc>https://guanghulab.com/api/ai/v1/repositories</loc><changefreq>daily</changefreq><priority>0.9</priority></url>
|
||||
<url><loc>https://guanghulab.com/api/ai/v1/nodes</loc><changefreq>daily</changefreq><priority>0.9</priority></url>
|
||||
<url><loc>https://guanghulab.com/fifth-domain/bingshuo/fifth-domain</loc><changefreq>daily</changefreq><priority>0.9</priority></url>
|
||||
</urlset>
|
||||
89
server-tools/guanghulab-front-door/styles.css
Normal file
89
server-tools/guanghulab-front-door/styles.css
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
:root {
|
||||
color-scheme: dark;
|
||||
--bg: #091112;
|
||||
--panel: #0d1819;
|
||||
--line: #213031;
|
||||
--text: #edf5f2;
|
||||
--muted: #94a6a1;
|
||||
--lake: #78d9c0;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
html { background: var(--bg); }
|
||||
body {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.topbar, main, footer { width: min(1040px, calc(100% - 40px)); margin-inline: auto; }
|
||||
|
||||
.topbar {
|
||||
height: 66px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; font-size: 17px; font-weight: 700; letter-spacing: .08em; }
|
||||
.brand span { color: var(--lake); font-size: 27px; line-height: 1; }
|
||||
.topbar p { margin: 0; display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; }
|
||||
.topbar i { width: 6px; height: 6px; border-radius: 50%; background: var(--lake); }
|
||||
|
||||
.hero { max-width: 760px; padding: 88px 0 82px; }
|
||||
.eyebrow { margin: 0 0 18px; color: var(--lake); font: 700 11px/1.2 ui-monospace, monospace; letter-spacing: .18em; }
|
||||
h1 { margin: 0; font-size: clamp(50px, 8vw, 82px); line-height: 1.02; letter-spacing: -.055em; }
|
||||
.intro { max-width: 670px; margin: 26px 0 0; color: var(--muted); font-size: 16px; line-height: 1.85; }
|
||||
.hero-actions { margin-top: 30px; display: flex; flex-wrap: wrap; align-items: center; gap: 22px; }
|
||||
.hero-actions a { display: inline-flex; gap: 18px; align-items: center; text-decoration: none; font-weight: 650; }
|
||||
.hero-actions a:not(.primary) { color: var(--muted); }
|
||||
.primary { padding: 13px 18px; border-radius: 9px; color: #071211; background: var(--lake); }
|
||||
|
||||
.routes { padding: 58px 0 22px; border-top: 1px solid var(--line); }
|
||||
.section-title { margin-bottom: 26px; }
|
||||
.section-title h2 { margin: 0; font-size: clamp(30px, 5vw, 42px); letter-spacing: -.035em; }
|
||||
.route-list { border-top: 1px solid var(--line); }
|
||||
.route {
|
||||
min-height: 150px;
|
||||
display: grid;
|
||||
grid-template-columns: 54px 1fr 24px;
|
||||
gap: 22px;
|
||||
align-items: center;
|
||||
padding: 28px 8px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
text-decoration: none;
|
||||
}
|
||||
.route.featured { background: var(--panel); padding-inline: 20px; }
|
||||
.number { color: var(--muted); font: 700 12px/1 ui-monospace, monospace; }
|
||||
.route p { margin: 0 0 10px; color: var(--lake); font: 700 10px/1 ui-monospace, monospace; letter-spacing: .13em; }
|
||||
.route h3 { margin: 0 0 9px; font-size: 24px; letter-spacing: -.02em; }
|
||||
.route small { display: block; max-width: 680px; color: var(--muted); font-size: 14px; line-height: 1.7; }
|
||||
.route b { color: var(--lake); font-size: 17px; }
|
||||
|
||||
.utilities { display: flex; flex-wrap: wrap; gap: 10px 24px; padding: 30px 0 64px; }
|
||||
.utilities a { color: var(--muted); font-size: 13px; text-underline-offset: 4px; }
|
||||
|
||||
footer {
|
||||
min-height: 100px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px 24px;
|
||||
border-top: 1px solid var(--line);
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
footer span:first-child { color: var(--text); }
|
||||
footer a { color: var(--muted); text-underline-offset: 4px; }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.topbar, main, footer { width: min(100% - 28px, 1040px); }
|
||||
.topbar p { font-size: 10px; }
|
||||
.hero { padding: 68px 0 64px; }
|
||||
h1 { font-size: clamp(46px, 15vw, 68px); }
|
||||
.route { grid-template-columns: 38px 1fr 18px; gap: 12px; padding-block: 24px; }
|
||||
.route.featured { padding-inline: 12px; }
|
||||
.route h3 { font-size: 21px; }
|
||||
footer { padding: 26px 0; }
|
||||
}
|
||||
68
server-tools/guanghulab-front-door/test/site.test.js
Normal file
68
server-tools/guanghulab-front-door/test/site.test.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("node:assert/strict");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const test = require("node:test");
|
||||
|
||||
const root = path.join(__dirname, "..");
|
||||
const html = fs.readFileSync(path.join(root, "index.html"), "utf8");
|
||||
const styles = fs.readFileSync(path.join(root, "styles.css"), "utf8");
|
||||
const robots = fs.readFileSync(path.join(root, "robots.txt"), "utf8");
|
||||
const llms = fs.readFileSync(path.join(root, "llms.txt"), "utf8");
|
||||
const installer = fs.readFileSync(path.join(root, "install-lite-front-door.py"), "utf8");
|
||||
|
||||
test("front door keeps the legally required ICP link", () => {
|
||||
assert.match(html, /陕ICP备2025071211号-1/);
|
||||
assert.match(html, /https:\/\/beian\.miit\.gov\.cn\//);
|
||||
});
|
||||
|
||||
test("front door makes the new code channel the primary route", () => {
|
||||
assert.match(html, /href="\/code\/"/);
|
||||
assert.match(html, /光湖代码频道/);
|
||||
assert.match(llms, /https:\/\/guanghulab\.com\/code\/bingshuo\/fifth-domain/);
|
||||
assert.match(robots, /Allow: \/code\//);
|
||||
});
|
||||
|
||||
test("front door preserves the legacy Fifth Domain as history", () => {
|
||||
assert.match(html, /href="\/fifth-domain\/bingshuo\/fifth-domain"/);
|
||||
assert.match(html, /第五域历史事实源/);
|
||||
assert.match(llms, /Legacy Fifth Domain history/);
|
||||
assert.match(html, /href="https:\/\/guanghubingshuo\.com\/code\/"/);
|
||||
});
|
||||
|
||||
test("AI discovery and search remain on the domestic domain", () => {
|
||||
assert.match(html, /href="\/api\/ai\/"/);
|
||||
assert.match(html, /href="\/api\/ai\/v1\/search\?q=/);
|
||||
assert.match(html, /SearchAction/);
|
||||
assert.match(html, /\.well-known\/guanghu\.json/);
|
||||
assert.match(llms, /HLCC-ICE-000001/);
|
||||
});
|
||||
|
||||
test("page is a script-free lightweight static surface", () => {
|
||||
const executableScripts = [...html.matchAll(/<script(?![^>]*type="application\/ld\+json")[^>]*>/g)];
|
||||
assert.equal(executableScripts.length, 0);
|
||||
assert.doesNotMatch(html, /<img|<svg|<video|<canvas|iframe/i);
|
||||
assert.doesNotMatch(styles, /linear-gradient|radial-gradient|animation:|backdrop-filter/i);
|
||||
assert.ok(Buffer.byteLength(html) + Buffer.byteLength(styles) < 16000);
|
||||
});
|
||||
|
||||
test("public page never embeds infrastructure addresses or credentials", () => {
|
||||
assert.doesNotMatch(html, /(?:\d{1,3}\.){3}\d{1,3}/);
|
||||
assert.doesNotMatch(html, /zy_gtw_/);
|
||||
assert.doesNotMatch(html, /password|private[_ -]?key|token/i);
|
||||
});
|
||||
|
||||
test("front door remains responsive", () => {
|
||||
assert.match(styles, /@media\s*\(max-width:\s*640px\)/);
|
||||
assert.match(styles, /clamp\(/);
|
||||
});
|
||||
|
||||
test("installer changes only the code route with backup and rollback", () => {
|
||||
assert.match(installer, /\/var\/backups\/guanghu\/front-door/);
|
||||
assert.match(installer, /proxy_pass http:\/\/127\.0\.0\.1:18088\/code\//);
|
||||
assert.match(installer, /nginx", "-t"/);
|
||||
assert.match(installer, /systemctl", "reload", "nginx"/);
|
||||
assert.match(installer, /legacy Fifth Domain verification failed/);
|
||||
assert.match(installer, /shutil\.copy2\(backup_root/);
|
||||
});
|
||||
Loading…
Reference in a new issue