Website From WebDAV
使用此技能将静态、已生成的 HTML/CSS/JS 网站——即 RDF-Turtle + SHACL + Jinja2 管道(如 sites/openlink/rdf/build.py)的输出——发布到 Virtuoso WebDAV 根目录并映射公共路由。网站的内容模型(本体、SHACL 形状、排序)在此技能上游进行创作和验证;此技能的工作从“这里有已完成的 HTML 的 generated/ 文件夹,让它上线”开始。
此技能故意比 weblog-from-webdav 或 osdi-inclusion-engine 更窄:那些技能在每次请求时实时渲染内容(在定制 VSP 中枚举 WebDAV 集合,或使用共享 XSLT 皮肤包装 WebDAV 来源的 HTML)。此技能的内容在到达之前已完全渲染——发布它只是简单的 WebDAV PUT 加上静态文件 VHOST_DEFINE,不涉及 VSP 执行,也没有实时 SPARQL 查询。请参阅 references/webdav-website-engine-gate.md 了解为何做出此选择以及何时会改变。
阻塞门控——本地文件不是有效完成
当用户要求发布、部署或“上线”已生成的网站时,描述将会发生什么,或声称文件存在于本地,不是有效完成,除非用户明确只要求本地/预览检查。默认交付物是:
- 已上线、已验证的已发布网站:目标路由返回与本地
generated/输出相同的内容,或 - 完整的可部署 bundle:
generated/*.html、网站的assets/(site.css、theme.js)、路径替换后的templates/deploy-website-route.sql,以及 README/运行说明文件——并且scripts/validate_generated_website_bundle.py对其执行通过。
在声称完成之前,请先阅读 references/webdav-website-engine-gate.md。如果部署凭据(WebDAV 和/或 isql)不可用,则停留在可部署 bundle 阶段,并明确说明实时发布因缺少已验证的访问权限而受阻——不要描述假设的成功。
首要决策
在发布任何内容之前,请先确定以下内容:
- 源管道目录(例如
{LLM_ROOT}/Claude Generated/sites/openlink/)以及是否需要(重新)运行rdf/build.py,或者generated/是否已是最新。 - 目标 DAV 集合,例如
/DAV/home/kidehen/sites/openlink/。 - 公共路由,例如
https://linkeddata.uriburner.com/sites/openlink/。 - 身份模式:SQL 用户名/密码、
isqlWebID-TLS、WebID-TLS 加委托、WebDAV 用户名/密码、WebDAV mTLS 或 WebDAV mTLS 加On-Behalf-Of。 - 这是首次路由引导(需要
isql+deploy-website-route.sql)还是仅内容重新发布到现有路由(仅 WebDAV 发布,根据references/webdav-publish-mode.md的范围外边界——它从不接触路由配置)。
工作流程
- 确认源
generated/输出是最新的:如果要求(重新)构建,则按原样运行管道自己的rdf/validate_shacl.py然后运行rdf/build.py——此技能不会重新实现或绕过该验证。请参阅references/rdf-content-mode.md。 - 在写入任何内容之前,搜索先前的内存/工作中是否存在
validate_generated_weblog_bundle、VHOST_DEFINE、DAV_RES_UPLOAD_STRSES_INT、website-from-webdav;重用经过验证的修复,而不是重新发现它们。 - 确定目标路由是否已存在(通过
isql查询目标路径的DB.DBA.HTTP_PATH和WS.WS.SYS_DAV_RES)。如果不存在,则引导它:用实际的 DAV 路径/路由/标题修补templates/deploy-website-route.sql,然后使用isql运行它。请参阅references/isql-route-mode.md。 - 在任何发布之前,使用
scripts/validate_generated_website_bundle.py验证 bundle。这是阻塞性的。 - 使用
scripts/publish_static_bundle.py通过 WebDAV 发布——递归地 PUTgenerated/*.html和assets/*,并通过后续 GET/PROPFIND 比较验证每次写入。请参阅references/webdav-publish-mode.md。 - 验证:获取实时路由,确认服务的字节与本地
generated/文件匹配(仅允许空白/属性顺序差异,与管道自己的 Phase 1 验证使用的相同容差),确认assets/site.css/theme.js以正确的 MIME 类型加载。 - 准确报告发生了什么:路由是引导的还是重用的,已发布的文件及其 DAV 路径,验证结果——或者,如果凭据缺失,则可部署 bundle 的位置以及明确说明实时发布未发生的陈述。
模式参考
- 对于路由引导和
isqlTLS/WebID 语法,请阅读references/isql-route-mode.md。 - 对于 WebDAV 发布及其范围外边界,请阅读
references/webdav-publish-mode.md。 - 对于管道边界(此技能在
rdf/中接触和不接触的内容),请阅读references/rdf-content-mode.md。 - 对于为何未选择实时 SPARQL/VSP 渲染,请阅读
references/webdav-website-engine-gate.md。 - 对于代理可调用操作,请阅读
references/opal-tool-mode.md——在 v1 中未实现;记录为扩展点。
实用护栏
- 切勿在抑制警告或使用
--skip-validate样式快捷键的情况下运行rdf/build.py的 SHACL 验证;失败的门控意味着内容尚未准备好发布,而不是可以绕过的障碍。 DB.DBA.DAV_RES_UPLOAD_STRSES_INT(如果用于任何非静态文件步骤)需要通过http(content, stream)填充的string_output()流,而不是纯字符串。- 避免在通过
isql加载的任何 SQL 中使用$1、$2和类似令牌;它们可能触发宏替换。 - 静态文件
VHOST_DEFINE使用is_dav=>1、is_brws=>0、def_page=>'index.html'——不要设置def_page=>'index.vsp',除非确实存在 VSP 入口点;指向不存在的 VSP 资源的def_page会提供原始源代码或 404,而不是网站。 - 在重新定义之前,删除同一主机/路径的任何先前冲突的
VHOST_DEFINE,与weblog-from-webdav的路由-删除-然后-重新定义模式相同。 - 将携带证书的身份和委托主体视为独立的事实:
-X/--cert标识调用代理,-W/On-Behalf-Of标识应评估其 ACL 权限的 WebID 主体。 - 切勿将凭据写入技能、生成的 SQL、日志或提交的文件中。
- 远程上传和删除遵循相同的 HTTP → WebDAV → iSQL 顺序和主体 PKCS#12 模式(
howto/remote-webdav-upload.ttl、howto/remote-resource-removal.ttl,prefs Steps 215–216)。URIBurner 的写入/删除转到端口 5443。在 PUT 之后分别报告:5443GET 和公共 443 GET;在 DELETE 之后,在声称删除之前验证用户命名的 URL、斜杠变体、:5443GET 和文件夹列表。
安全的 Virtuoso ISQL 错误输出
每当此工作流调用 OpenLink 的本机 Virtuoso isql 客户端时,传递裸客户端选项 COMMAND_TEXT_ON_ERROR=OFF,例如 isql {host}:{port} {user} {password} COMMAND_TEXT_ON_ERROR=OFF {script.sql}。将其放在 SQL 输入、脚本参数或 -i 之前。OFF 映射到客户端的内部值 0,并阻止客户端将完整的失败命令附加到错误输出。客户端接受 OFF/ON;不接受文字 0。不要为此设置使用 -u(-u 填充 U 参数数组)。这不会从服务器诊断、shell 历史或进程参数中删除秘密,因此请将凭据保留在 SQL 文本和日志之外。不要将此 Virtuoso 特定选项应用于 unixODBC/iODBC isql 客户端。