浅念
|
e6c8cb9ce6
|
chore(theme): astro 锁定 ~5.18.0(终审 Minor)+ docs: Plan 4 收官
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 16:16:03 +08:00 |
|
浅念
|
87d6b9a777
|
docs: ADR-018/README/Plan 5 移交清单
Plan 4 Task 9 收尾(阶段 4 收官):
- ADR-018(主题与构建决策八条):Astro 5.18 选型与 MIT/依赖只进主题包/
vitest 双版本(根 2.1.9 + 主题 3.2.7——astro vite6 兼容);渲染信任链
bodyHtml 不二次清洗(三段接力);分页 V1 不做——路由登记义务随迁移移交;
P0 发布门禁偏离(issue 无 DB 源,Plan 5 SEO diff 重审);编码路径四层
字节精确 + 资产键 URL 线形归一(236f3dc);预览零依赖 + host 白名单
收紧(回环纪律,比 spec §12.2 更严);CSP style-src 'unsafe-inline'
(Astro scoped 样式内联);报告 HTML 先写两域对齐
- README:快速开始补 publish→build→preview 全链命令链示例(含
artifacts/jobs/<jobId>/ 产物路径);目录结构补 themes/ 与
apps/preview-server/;当前状态阶段 4 完成(真实 hesupipe 190 页可
浏览器预览/408 测试/23 验收断言/6 截图);ADR-001~018 导航;下一步
指向 Plan 4 文末移交清单
- Plan 4 文档:Task 9 勾选 + 验收节 ✅ 全过;文末新增"移交 Plan 5 清单"
7 项(SEO 三方 diff 新输入源/完整门禁六件含可复现双构建与 footer 年份
固定化/sitemap-robots 预览可达/og 元数据/836 nginx conf 输出/Task 0.2
备份续传/度量基线 ~64s 首跑·~15s 复跑)
三绿全量:lint 过 / typecheck 五段过 / test 408(根 382 + 主题 26)全绿。
不 push——推送由用户执行。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 15:59:48 +08:00 |
|
浅念
|
5c2ee7dc5d
|
refactor(test): 三份 helper 迁移共享
Task 6 审查遗留①(schema 再演进防漂移):makeWork / seedPublishedSite /
cleanupSiteRows 三件套自 build-snapshot / build-pipeline / build-gates /
preview-server 四文件(Task 6 审查时三份,Task 7 又落一份)迁
tests/integration/helpers.ts 共享——清场清单(21 语句 FK 反序 + 不可变
触发器开关)此后只改一处。
- makeWork 保持签名;媒体种子载荷改由 prefix 派生(bytes 仍随机唯一,
魔数校验只看 PNG 签名——行为等价);shared Work 统一携带 pngA/pngB
- seedPublishedSite 增 keyPrefix 参数(各文件沿用原站点 key 派生前缀
sfbuild/sfpipe/sfgate/sfpreview);succeeded_with_issues 与
publishedCount=3 断言随迁(gallery 203/204 悬空语义文件无关)
- import 域短清单清场与 publish 域各自形状不同,不共用——保留原处
零行为变更由 408 测试守护(全绿:根 382 + 主题 26);lint/typecheck 五段过。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 15:55:43 +08:00 |
|
浅念
|
7e4cf11452
|
docs(plan): P4 Task 8 勾选——浏览器时刻兑现
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 15:34:02 +08:00 |
|
浅念
|
236f3dc4d3
|
fix(preview+pipeline): 资产键编码归一——7 张全角名图片预览 404 修复;证据文档叙述修正
spec 复审发现(浏览器可见缺陷):manifest 资产行 exact_key 有 7 例为裸形
(文件名含全角括号/顿号/间隔号)——html/redirect 键源数据侧已编码、asset
键来自文件名本体是裸形;浏览器对裸非 ASCII 一律百分号编码后发请求,预览
按请求字节逐字匹配 → 裸键永不命中 → 两页 3 张图破图(dist 文件在盘;
生产面 nginx 先解码不受影响)。修补 pipeline.toManifestRoute:exact_key
归一为 URL 线形(可打印 ASCII 原样、其余 UTF-8 百分号编码大写 hex),
target_file 仍盘上裸名、DB/渲染快照域不变。
回归三层:build-pipeline 注入裸全角资产行(红验证);preview-server 2c
非 ASCII redirect → Location → 资产终端 200;e2e 断言 ④c(7 条全查
跟随到终端 200)+ ⑦c(manifest 2772 键全 ASCII 不变量)。spec 复审复跑
(新库全链 job e059bf41)23/23 PASS,浏览器实测 3 张原破图全部加载。
证据文档:§5.2 失败计数修正(5×500+2×mojibake=7 例)、§2 ①c 措辞对齐
断言实义(抽前 3 标题)、§5.5 修补记录、计时/产物/job 面更新至复跑值。
验证:vitest 382 + 主题 26 全绿(408);typecheck 过;lint 裸跑零告警。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 15:31:14 +08:00 |
|
浅念
|
c64f6ac48a
|
test(evidence): 阶段4端到端预览验收
Plan 4 Task 8:真实 hesupipe 全链(register 副本复用 → import → publish
→ build → preview)临时库端到端验收,断言 21/21 PASS + 浏览器时刻 6 截图
无破版无横向溢出。新增 scripts/e2e-real.mjs(chain/serve 两子命令)与
docs/evidence/phase4-preview.md + phase4-assertions.json + screenshots/。
验收内修补(预览服务器,均有回归测试锁定):
- Location 头 ASCII 化:非 ASCII 码位按 UTF-8 百分号编码——原样 setHeader
触发 ERR_INVALID_CHAR 崩 500 或 latin1 mojibake(1746 redirect 全量
校验显影 2+3 例);manifest 原串保持权威,测试 2b 锁定。
- CSP 放行内联样式:Astro 5 scoped 样式内联 <style> 被 default-src 'self'
拦截(浏览器时刻显影,HTTP 级不可见);测试 6 断言同步。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 14:33:55 +08:00 |
|
浅念
|
66ca95d37f
|
docs(plan): P4 Task 7 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 13:59:23 +08:00 |
|
浅念
|
5f78dde9ee
|
fix(preview): 流式文件服务与 HEAD 跳读;静默开关;redirect 转义;argv 缺值报错
复审四项:
- serveFile 改 createReadStream 直 pipe(Content-Length 取自先行 stat)——
64MB 文件 RSS 平坦(冒烟实测 -53MB 增长,此前整读驻留);HEAD 只发头
零读盘;流错误掐断连接不崩进程;头纪律抽 applyHeaders 唯一出口。
- createPreviewServer 增 quiet 选项(缺省 verbose);sf.ts preview:start
与 server.mjs 直跑入口各加 --quiet;CLI 透传经子进程冒烟验证。
- redirect 迁移页内嵌 location 时 HTML 转义(</&/"——Location 头原样)。
- parseCliArgs 末尾缺值 flag 显式报错(不再静默 undefined 漏成默认值)。
测试 12→13(新增 quiet 开关用例;用例 12 增 --quiet stdout 断言):
根套件 380 + 主题 26 = 406 全绿;typecheck/lint 干净。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 13:58:15 +08:00 |
|
浅念
|
7194d1bcef
|
feat(preview): 路由驱动的本地预览服务器
Plan 4 Task 7(V2 spec §12.2):apps/preview-server 零依赖 node:http 服务——
只读 succeeded job 的 dist + route-manifest(不查库),exact/ignore 双索引匹配
(query_key 行全串优先),html/asset 文件服务(manifest content_type 优先、
扩展名 MIME 表兜底、未知扩展 octet-stream)、redirect 301+Location、gone 410、
未命中 404 走 dist/404.html 自定义页;全响应 X-Robots-Tag noindex + HTML 响应
基础 CSP;回环绑定白名单(库级即拒);穿越预检先于 URL 解析(裸/编码点段、
反斜杠)+ target_file resolve+realpath 双检在 dist 内;目录请求一律 404(禁
列表);仅 GET/HEAD。sf.ts 增 preview:start(job 定位 + succeeded 校验 + 产物
行读取后即断池;--host 外值拒绝先于 DB 访问)。集成测试 12 例:真实构建产物
全链 + 手构 gone/MIME 探针行 + CLI 拒绝与子进程 happy path 冒烟。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 13:29:30 +08:00 |
|
浅念
|
0efec4673b
|
docs(plan): P4 Task 6 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 13:08:49 +08:00 |
|
浅念
|
fa27a3a308
|
fix(build): validation_issues 分批插入;import/build 报告写序对齐 HTML 先;canonical mismatch evidence 修正
- validation_issues 落库改分批(VALIDATION_ISSUES_CHUNK=1000 行/批循环):
单 INSERT 占位符上限(pg ~65535 ÷ 6 列)会被超大 issue 集撞穿;
run 行先落、批次间无序依赖。新增测试:1101 坏链注入 → 全量 1101 行
落库、收口 VALIDATION_FAILED(非 GATE_INTERNAL)
- import 域报告写序换 HTML 先(与 build 域对齐——json 在则 html 必在)
- gates canonical 指错分支 evidence 改 kind:'canonical-mismatch'
(mismatch 语义不再误用 missing 键;缺席分支保持 missing:'canonical')
- build.html 尾换行对齐 import 域
- 计划文档 Task 9 补审查遗留清单(helper 迁移/Plan 5 前置门禁面)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 13:07:01 +08:00 |
|
浅念
|
8f2b9825a6
|
feat(build): 最小门禁与状态机闭环
Task 6(Plan 4):validating 接真实门禁——五项产物检查(①内部死链 ②sitemap
一致 ③SEO 基线 ④大小写冲突 ⑤产物完整性),P0 阻断/P2 报告分级;validation_
runs/validation_issues 落库(severity/rule/url/evidence),任一 P0 → job failed
(VALIDATION_FAILED + 产物清场),全过 → succeeded。HTML 解析用 htmlparser2
(sanitize-html 既有传递依赖,lock 已解析 12.0.0——apps/api 显式声明复用,零新
包版本),禁正则提标签。报告 json/html 双落盘且 HTML 先写(Plan 3 窄窗口修,
html 转义模板)。顺手:build-snapshot 测试 spawn 缩减 7→2(六文件物化/bodyHtml
重写/ADR-010 改 materializeRenderSnapshot 直调;复用两场景并谱共享单次成功构建),
根套件 97.3s→75.8s;两测试文件清场补 validation 域反序(FK 链先行)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 12:29:48 +08:00 |
|
浅念
|
3e436d907a
|
docs(plan): P4 Task 5 勾选补全
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 11:53:32 +08:00 |
|
浅念
|
06ba069f9c
|
fix(build): taskkill error 监听回退单杀(终验 nit)+ docs: P4 Task 5 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 11:53:01 +08:00 |
|
浅念
|
41829e2665
|
fix(build): Windows 树杀与错误码分阶段包裹;清残覆盖 manifest;反斜杠守卫与 stat 收窄
质量复审五修(Plan 4 Task 5):
- Fix 1 超时杀整棵进程树:win32 走 taskkill /PID /T /F(child.kill 只杀
pnpm.cmd 壳层,astro/vite 孤儿会继续写 dist 并占句柄);POSIX detached
进程组 + kill(-pgid, SIGKILL)。暂存 dist 预清 rm 包成 THEME_BUILD_FAILED
(孤儿句柄 EPERM 不再裸抛误标 SNAPSHOT_FAILED)。
- Fix 2 五处裸抛分阶段裹码:媒体校验读回 → MEDIA_COPY_FAILED;sitemap/
robots 写、dist 拷出、目录哈希 → MANIFEST_WRITE_FAILED;service 对
building 期非 PipelineError 裸错误标 PIPELINE_INTERNAL(码位新增)。
- Fix 3 失败清残覆盖 route-manifest.json;build_artifacts 已登记行注明
审计豁免(与快照行同语义)。
- Fix 4 媒体 public_path 反斜杠拒绝(Windows 路径解析会绕过 '/'-split
的 '..' 段检测)。
- Fix 5 stat 缺席语义缩窄到 ENOENT,其余错误原样上抛。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 11:30:05 +08:00 |
|
浅念
|
1ed3ac062a
|
feat(build): astro 构建管线与媒体落盘
Plan 4 Task 5:build.service snapshotting 后接真实构建——building 态进
pipeline.ts(spawn `pnpm --filter @sf/theme-pilot-minimal exec astro build`
(SF_BUILD_INPUT env;非零退出+stderr 标记判据)→ dist 定位与 target_file
完整性 → 媒体 copyPath→dist/public_path(sha256 全量校验)→ sitemap.xml/
robots.txt(编码 URL 原样)→ route-manifest.json(§12.1 字段面、哈希链复用)
→ build_artifacts dist/manifest 登记)→ validating(空,Task 6) → 报告+report
行 → succeeded;失败任何一步 failed+error_code/error_summary(stderr 摘要)
+input/dist 清残。
dist 双位置纪律:主题包 dist 是暂存,产物汇齐后拷出 <artifactsRoot>/jobs/
<jobId>/dist(job 级权威),暂存随即清空。无网证明:ASTRO_TELEMETRY_DISABLED=1
(实测 @astrojs/telemetry 构建期真调 fetch)+ NODE_OPTIONS 透传(测试注入
fetch/net stub 构建仍成功)。主题集成补面:ProductList 模板 + /products/
主列表分派特判(DB 物化形状 targetContentId=null,Task 4 夹具曾被占位绕过)。
测试:tests/integration/build-pipeline.test.ts 五用例(全链/夹具直跑/五禁
断言/失败路径);build-snapshot 状态机补 building + 清场补 build_artifacts。
root 359 + theme 26 全绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 10:52:13 +08:00 |
|
浅念
|
107642c1b3
|
docs(plan): P4 Task 4 勾选 + Task 8 分派观察项
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 10:06:38 +08:00 |
|
浅念
|
0a7578b5eb
|
chore(theme): dist 根 stub 清理归属钩子;build.format 显式契约
sf-literal-html-paths 钩子收尾清理 astro 5.18.2 内容层无条件发射的
content-assets.mjs/content-modules.mjs(content/consts.js
ASSET_IMPORTS_FILE——本主题零内容集合,dist 树=target_file 面);
build.format:'directory' 由缺省依赖升为显式契约,*.html.html 残留
自检守护折平前提(偏离即构建明错)。render-cases 钉死 dist 根无 stub。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 10:05:57 +08:00 |
|
浅念
|
f916f723ab
|
feat(theme): 六类页面渲染与路由分派
单一动态路由 [...slug].astro 读 routes.json html 纯路径行分派六模板
(home/typeKey 详情/分类前缀列表/news 主列表),无法分派即构建明错;
404 独立静态页。夹具扩展为六页集(真实 hesupipe 抽样形状脱敏化:
knownFields.postDate/title、media 块 attachmentRefs.* fieldPath、
/products/ 内容页占据、编码路径 + .html 字面路径防御)。
字面 .html 路径对齐钩子(astro.config 内联 integration):Astro 页面
产物在 directory/file/preserve 三态均产不出 dist/news/x.html 字面文件,
构建收尾把包装目录折平为字面文件——target_file 契约对齐。
构建级测试 8 例(render-cases):全量映射/编码字节原样/首页截断/
产品参数相册/新闻字面 .html/列表两类/SEO 基线。372 → 380。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 09:34:58 +08:00 |
|
浅念
|
097cfd5609
|
docs(plan): P4 Task 3 勾选 + Task 5 备忘(包名 filter/Windows 退出码判据)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 09:03:14 +08:00 |
|
浅念
|
eb81a57ebc
|
fix(theme): payload 契约上提 contracts;空路由明错;ui.routeHrefFor;eslint astro ignore
审查修复(Plan 4 Task 3 review):
- 载荷类型单一事实来源:ContentEntry/TaxonomyEntry/TaxonomyTerm/RouteEntry/
AssetEntry/RenderManifestMeta/SiteConfigPayload/BrandConfigPayload 上提
@sf/contracts/render-snapshot(纯新增、不动既有导出——冻结面加法无需升版);
物化端(apps/api build/render-snapshot.ts)与主题 load-render-data 同源引用,
双份手写镜像漂移即编译期破裂;主题侧 re-export 保持既有 import 面
- loader 空路由表前置明错(正常发布站点至少含首页路由——静默渲染会产零页站点)
- ui.routeHrefFor:targetContentId → 纯路径 html 落点(redirect/查询行不参与,
无落点 undefined 不虚构——Task 4 分派器入口)+ 测试
- 具夹 assets.json copyPath 去机器相关绝对路径(改仓库相对)
- eslint ignores 增 **/.astro/**(astro build 再生目录)
354 根测试 + 18 主题测试全绿;五段 typecheck;lint(.astro 存在态验证后清理)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 08:58:33 +08:00 |
|
浅念
|
1cd309d56d
|
feat(theme): pilot-minimal 骨架与布局组件
Plan 4 Task 3:
- themes/pilot-minimal 入 workspace(astro ^5.18 纯静态;依赖仅 astro)
- theme.manifest:contracts isThemeManifest 守卫通过——key=pilot-minimal/
七模板条目(home/page/product-list/product-detail/news-list/news-detail/
not-found);brand 刻意不入 requiredSiteConfig(恒可能 {},Task 1 移交契约)
- load-render-data:全主题唯一取数入口(五禁纪律结构保证,JSDoc 钉死)——
SF_BUILD_INPUT 六文件、缺文件/形状破裂明确错误不静默空、同目录缓存单例、
name 空→'Untitled Site'/brand 缺席→{}、编码 slug 原样贯穿(源码令牌扫描
禁 percent-decode)
- 布局/组件:BaseLayout/SeoHead(title/desc/canonical/og)/SiteHeader(导航
路由缺席容忍隐藏)/SiteFooter/RichText(信任链:清洗+重写后直出)/
ResponsiveMedia/Breadcrumbs/ProductCard/NewsCard/Pagination(V1 禁用态)/
NotFound + tokens.css(75rem/系统字体/4-8-16-24-48/中性色+单 accent)
- 根 test 链并入主题(vitest 3 + astro getViteConfig,Container API 组件
渲染测试);typecheck 四段变五段;.astro/ 入 gitignore
354 根测试 + 16 主题测试全绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 08:38:00 +08:00 |
|
浅念
|
56e4ca96e7
|
docs(plan): P4 Task 2 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 08:18:57 +08:00 |
|
浅念
|
5434afefff
|
fix(build): 哈希链含尾换行;media 块 first-wins 确定性;job 复用只认 succeeded+崩溃回收;重写器边界锚定
审查六修(Fix 2/3 先于 Task 3 消费六文件落形):
- Fix 1 三哈希 = sha256(文件字节含尾换行)——哈希链与落盘文件互证;测试改按
原始文件字节独立复算对拍
- Fix 2 media_usages orderBy(fieldPath, publicPath) + first-wins:同 fieldPath
多资产引用取字典序首位、其余丢弃记 issue;两次物化字节一致有测试钉死
- Fix 3 job 复用只认 succeeded;failed/cancelled/stale 死行与非终态崩溃残留
(旧行置 stale 宣判)都以 <key>#a<attempt+1> 后缀键建新行自动重跑(attempt
延续谱系);失败终态化时清走半途 input/ 目录;两路径各有测试
- Fix 4 git rev-parse 等环境探测移出快照事务(单次探测传入)
- Fix 5 属性正则边界锚定 (^|\s):data-src 等连字属性不卷入(\b 会误判 '-s'
交界)——data-src 命中索引也不改写的用例钉死
- Fix 6 media 引用面只 join ready 资产;非 ready 残留引用单独查出记 issue、
不进 content.json media 块(quarantined 翻转测试)
354/354(350+4);typecheck 四段、lint 全绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 08:12:59 +08:00 |
|
浅念
|
8f42c838c1
|
feat(build): 冻结 Render Snapshot 物化与 build job
Plan 4 Task 2:build_jobs 生命周期(queued→snapshotting→validating(空)→succeeded)
+ build_input_snapshots 行(三哈希/主题/config 引用/真实版本列)+ 六文件物化
(site/content/taxonomies/routes/assets/render-manifest——canonicalJson 确定性落盘)。
- render-snapshot.ts:纯物化(db 只读)——published 修订(ADR-010 冻结语义)+
路由/媒体 ready 集合 → 六文件;bodyHtml URL 重写(剥 host 按 path 与 ready 集合
public_path/source_url 双源比对,命中根相对化、未命中保留+计数);媒体实体路径
三候选解析(快照 storageRoot→仓库存储根→incoming 兜底)
- build.service.ts:幂等键 = site+published 集合哈希+主题版本(复用不重跑);
repeatable read 单事务一致性读取+落盘+快照行;报告 artifacts/jobs/<id>/reports/
build.json 先于终态落行;解析期失败零 job 行(NOT_PUBLISHED/SITE_NOT_FOUND)
- sf.ts + build:create;build.module.ts Nest 薄壳
- tests/integration/build-snapshot.test.ts:10 测试(状态机/六文件面/URL 重写/
字节确定性/NOT_PUBLISHED/ADR-010 双修订/重写器纯函数四例)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 07:46:23 +08:00 |
|
浅念
|
6d681f24ef
|
chore: 移除误入库的会话锁文件并忽略 .claude/
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 07:22:15 +08:00 |
|
浅念
|
5686c5c8ba
|
docs(plan): P4 Task 1 勾选 + brand 容忍契约入 Task 3
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 07:21:59 +08:00 |
|
浅念
|
6a1d9a383b
|
chore(publish): locale 决胜键;confirm 清单输出;并发窗口注释
- 候选查询 orderBy 第三键 entry_locales.locale(同 typeKey+slug 多 locale 决胜,
清单呈现稳定);mini 单 locale,既有测试期望三元组已含 locale 列、无需改
- CLI confirm 输出发布清单(result.candidates,与 dry-run 同行格式
published→current;>20 行截断为 …and M more——CONFIRM_LIST_CAP)
- PublishSiteContentResult.candidates 注释钉死:confirm 期 candidates 是事务前
快照,权威数以 publishedCount 为准(并发窗口)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 07:21:34 +08:00 |
|
浅念
|
c35f10835a
|
feat(publish): 显式发布命令(dry-run/confirm/审计/站点配置首版/锚点helper)
- publishSiteContent 零装饰器服务:dry-run 只读清单(current 非空且 published≠current)
+ 随机 confirm token;confirm 单事务批量 UPDATE published←current + audit_logs
(action=content.publish,全仓第一个审计写入方)+ site_config_revisions v1 首版
({name,origin,locale,brand:{}},UNIQUE(site_id,version) 幂等)
- 空清单 no-op 零写入;SITE_NOT_FOUND/CONFIRM_TOKEN_REQUIRED 均先于任何写入
- P0 门禁不做(ADR-018 记偏离,服务 JSDoc 注明);导入永不发布(ADR-010)
- sf CLI + content:publish(--dry-run/--confirm/--actor,缺省 dry-run 安全优先,
actor 缺省 super_admin@cli)
- anchors.ts:五列内容身份查询从 content/term/route 三写入器抽单源共享(零行为
变更,既有 333 测试守护)
- 集成测试 7 例(临时库 mini 全链):dry-run 零写入/confirm/幂等/config 首版与
既有跳过/actor/空清单/SITE_NOT_FOUND/缺 token
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-22 07:06:23 +08:00 |
|
浅念
|
a009f49961
|
docs(plan): Plan 4 终审定稿——ADR-018 枚举补全
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 22:48:09 +08:00 |
|
浅念
|
63056d33cf
|
docs(plan): Plan 4 修复评审三 Issue 与建议——编码路径贯穿规则(54 条真实数据实测)、发布 actor/P0 门禁决策、无网证明测试、route-manifest 认领、URL 重写匹配键、ADR-010 双修订测试、分页统一不做、410/CSP/目录列表、redirect 全量与桌面截图
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 22:46:30 +08:00 |
|
浅念
|
171137bc8e
|
docs(plan): Plan 4 实施计划——阶段4 发布/主题/构建/预览(9任务,浏览器时刻)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 22:34:57 +08:00 |
|
浅念
|
066ba289bb
|
docs(plan): Plan 3 收官——移交清单第 9 项终审既定事实
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 21:27:58 +08:00 |
|
浅念
|
fc36239b35
|
docs: Plan 3 终审收官——ADR-017 补决策六/七(is_primary first-import-wins、§7.6 事务粒度偏差),移交清单补三点既定事实
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 21:27:16 +08:00 |
|
浅念
|
6d9f7b6ad7
|
docs: ADR-017/README/阶段4移交清单
- ADR-017 导入管道决策五项:幂等双轨身份键(六列快照行+五列内容身份)与
canonical.ts 共享 checksum 输入域/收编 UPDATE 语义;自建 term((domain,nicename)
兜底 + auto: 前缀 + name 回退 + 双序终态等价含 null-id 收编);counts 键全局
命名空间求和聚合;stale 回收维持 created_at 近似 + 24h 不加心跳列(REST 化重审)
与报告 issues 封顶;编排串行分派契约(锚点依赖推导)
- README:快速开始加 sf import 全链示例(register→import);当前状态更新
(阶段 3 完成:192 条目真实落库/二导幂等 0 新修订/333 测试);ADR-001~017
- Plan 3 计划文档:Task 8 勾选 + 验收 6 项全过核验 + 文末新增"移交 Plan 4 清单"
8 项(publish 命令/Render Snapshot 六文件/pilot-minimal 六类页面+Astro 五禁/
Preview Server/最小门禁/导入产物消费接口与副本路径/续传项/度量基线 51.8s·20.3s·304MiB)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 21:20:21 +08:00 |
|
浅念
|
a7177afde7
|
feat(import): HTML 报告与错误封顶;orchestrator 抽取
- report-html.ts:renderImportReportHtml(Plan 2 Task 6 模板纪律——全动态文本
转义/静态骨架无 script/分组固定序渲染/封顶注记),import.html 与 import.json
同 try 原子落盘(同 REPORT_WRITE_FAILED 失败口径)
- 报告 issues 封顶(Task 6 推迟项):REPORT_ISSUES_CAP=10k——flat 清单与
issueGroups 各组同限截断 + issuesTruncated 计数;终态判定(succeeded_with_issues)
在全量长度上做,截断不吞终态事实;counts/sanitize 始终完整
- orchestrator.ts 抽取(审查触发器 import.service 849 行):orchestratedPipeline/
mergeOutcomes/sumCounts/trySyncFinish 迁出为纯函数 over ctx;契约类型单源
import.service.ts 不动;既有测试全绿即证零行为变更
- 测试 +8:单元 7(恶意 payload 转义/结构/分组序/封顶注记/渲染不改输入)+
集成 1(10_003 条注入:截断计数/JSON 原文保留/HTML 转义/终态判定);333 全绿
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 21:20:12 +08:00 |
|
浅念
|
3776a0d6ad
|
docs(plan): P3 Task 7 勾选——真实全量导入验收通过
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 21:04:40 +08:00 |
|
浅念
|
1c4c163743
|
test(evidence): 阶段3真实全量导入验收
Plan 3 Task 7:真实 hesupipe 输入(WXR 5.5MB + 媒体 2625 文件/164.53MiB + 侧车 859 条)
全量导入验收证据——断言总表 21 项全过(content_entries=192 / source_records=1122 /
terms=451+476 自建 / media_assets=836 全侧车二级命中+19 missing 全列 / routes=2772
逐桶闭合 / published 指针全程未动);换 key 二导全幂等(五表行数不变);临时库验后
DROP;storage/incoming 副本保留(Plan 4 构建用)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:54:28 +08:00 |
|
浅念
|
cf6193acc5
|
docs(plan): P3 Task 6 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:40:51 +08:00 |
|
浅念
|
fa6e8a35dc
|
chore(import): 终验三处一行补完——fact-12 JSDoc 分层和解、flush 措辞、tsbuildignore
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:40:30 +08:00 |
|
浅念
|
77687e2330
|
fix(import): 失败报告部分冲刷;列表路径校验(建行前);JSDoc 求和措辞;reason 归档
Task 6 质量评审四项修复:
- 失败报告部分冲刷(Fix 1):orchestratedPipeline 分派/finish 包 try/catch——
中途抛错时把可安全取得的部分产出冲入 ctx.report 后重抛:term/content 的
finish 是纯返回(已算成复用、未算成就地补算 trySyncFinish,自身抛错放弃
该部分不掩盖原错)、已收集的 adapter 问题/清洗统计、进度计数
eventsDispatched(orchestrator 键,仅失败路径出现——成功路径不占 18 键面)。
media/route finish 依赖库与先序产物,失败路径不调用(其键缺席如实反映)。
- 列表路径校验(Fix 3):ImportErrorCode 增 INVALID_LIST_PATH;解析期防线
移至阶段 2.5(建 job 行前——建行/置 running 后再抛会留悬挂行);复用
route-writer 导出的 isSafePath;normalizeListPath 自带安全拒绝(写入器
自调用位双覆盖)。CLI 无需新码(既有 ImportError 通道按 code 呈现)。
- JSDoc 求和措辞(Fix 2):content-writer/media-writer 的 counts 键契约
注记由"返回值覆盖同名键 CLOBBER"改为"同名键求和(Task 6 钉死——防覆盖
安全网)",与 ImportPipelineOutcome.counts 契约对齐。
- reason 归档(Fix 4):分派循环对 unsupported/error 事件把 reason/issue
推入 adapter 问题组(此前被静默丢弃)。
测试:import-full 增 2 例(手构流 3 事件后爆炸 → failed + eventsDispatched=3
+ 部分 content/term 计数 + unsupported/error reason 双归档;--products-path
/../x/ 等 → INVALID_LIST_PATH 零 job 行)。全量 325 通过;typecheck/lint 干净。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:34:43 +08:00 |
|
浅念
|
8003de336b
|
feat(import): 全链编排与导入报告
Task 6(Plan 3):四家写入器汇流为默认编排管道。
- import.service:注入 events/pipeline 缺席时走真实事件流(runWxrAdapter
惰性 async generator,mapConfig.locale=site.default_locale 前置事实 8);
分派严格串行 content→term→media→route(禁 Promise.all);finish 硬序
term(sync)→content(sync)→media(await)→route(await);counts 由 ⊕ 覆盖
改为逐 key 求和聚合;新增 stale 回收(同站点 queued/running >24h 一条
SQL 置 stale);报告新增 paths/productsPath+newsPath、issueGroups 六组、
sanitize 清洗统计(事件流 changedRows/byDiffType 聚合)、adapterTiming。
- content-writer:NULL-entry 收编(快照行在而 content_entry 空,五列先验
三分支:无先验新建挂接/同 checksum 挂接 skipped/异 checksum 挂接新版本)。
- route-writer:attachment 降级汇总按去重 sourceId 计(重跑仍必现);
normalizeListPath 导出;writeAttachmentRoute 返回 written/resolved/blocked。
- 四家写入器 identity 收敛共享基类型 WriterContext =
Pick<ImportJobContext,'db'|'siteId'|'connectionId'>(type-only import,
无运行时环依赖)。
- CLI import 增 --products-path/--news-path(前置事实 9,缺省 /products/
/news/)记入 job 报告。
- 测试:tests/integration/import-full.test.ts 6 例(全链 zh-CN 接线证明
+published 全 NULL/报告四域计数+sanitize+分组/幂等重跑零写语义/
无 media 快照域缺失不失败/NULL-entry 收编/stale 回收/REPORT_WRITE_FAILED
遗留补测);import-job 契约测试钉死 counts 求和(100⊕3=103)。
全量 323 通过;typecheck/lint 干净。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 20:08:06 +08:00 |
|
浅念
|
27a8282367
|
docs(plan): P3 Task 5 终验注记补全
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 19:46:05 +08:00 |
|
浅念
|
15d7c91648
|
docs(plan): P3 Task 5 审查移交的 Task 6 汇流契约底本
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 19:40:35 +08:00 |
|
浅念
|
bb2d381308
|
fix(import): finish 域路径安全守卫;attachment ?p= 排除对齐;歧义/降级计数精化;permalink 形态覆盖
- isSafePath 扩至 finish 域②(分类页 public_base_path+slug)与域④(media_assets public_path)——WXR 原始 slug 与库表原样切片同携穿越向量,拒绝即 issue+不登记
- writeAttachmentRoute 与内容行同口径排除 ?p=/&page_id=(?attachment_id= 不在排除表,照常 query_key 建模),排除计数 routesExcludedQueries
- 多资产歧义消息改"命中 ≥2 行"(LIMIT 2 探针只知下界)
- 降级汇总去虚报:writeRoute 返回四态,downgraded 只计实际写入(created/updated)——重复 attachment 事件 no-op 不重复计数
- foldCollisionKey JSDoc 钉死:折叠仅 JS 侧计算落列,勿用 PG normalize 库侧重算(ICU 版本差异面)
- 测试补 permalink 形态 attachment 301(纯路径行 query_key NULL)+ 重复事件降级计数"1 条"断言 + 双 finish 域安全守卫拒绝用例(317 全绿)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 19:40:35 +08:00 |
|
浅念
|
fae44a11f8
|
docs(plan): P3 Task 5 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 19:15:38 +08:00 |
|
浅念
|
9d2cc0a46d
|
feat(import): 路由注册表生成
§6.1 处置全表落 route_registry(route 域唯一写入方):
- 内容 permalink → html(路径保真 + target_content_id 经 source_records 关联);
首页 / 与主列表 /products/ /news/(CLI 参数注入)finish 期生成;
- category/product_cat → html(public_base_path 常量 + term slug);post_tag/
product_tag → 301 对应主列表(terms×taxonomies 全表 finish 期生成);
- attachment 页一律 301 媒体文件(前置事实 10 降级一条汇总 issue;暂存事件、
finish 反查 media_assets——依赖 media-writer 先落资产的时序契约);
?attachment_id= 查询形态走 query_key 单独建模(spec §5.6 查询路由不并 path);
- 上传媒体路径 → asset(media_assets 全表;target_file 为产物路径占位);
- ?p=/&page_id= 不插行(route_kind 六值无 excluded——查询路由 SP3),计数
routesExcludedQueries + 逐条 issue 落 excluded_with_reason 报告语义;
- ADR-007 双键:/About 与 /about 并存 + collision_key 折叠预警不计失败;
同 exact_key 异 owner 冲突保留先到 + issue 列后者;
- upsert 三分:miss INSERT / 同 owner 描述字段 diff UPDATE / 异 owner 冲突;
幂等重跑零计数,--news-path 变化触发 tag 301 目标同行 UPDATE。
counts 独占五键(route 前缀):routesCreated/routesUpdated/routesRedirects/
routesCollisions/routesExcludedQueries。315 测试(+5);typecheck/lint 绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 19:15:21 +08:00 |
|
浅念
|
c8a2ed81e5
|
docs(plan): P3 Task 4 勾选 + Task 7 度量口径
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:56:44 +08:00 |
|
浅念
|
7e6ce91001
|
fix(import): 媒体工厂守卫与加固——manifest 形态/侧车门控/冲突约束名/窗口边界与冲突测试
评审加固五项:
- manifest 形态守卫:bundle 在场而 metadata.manifest 非数组 → throw(与
storageRoot 守卫同风格),不与"bundle 合法缺席=空清单"共用静默空 coercion
- 侧车门控:空清单下级②不可达,跳过侧车加载——破损侧车副本不因无用输入
让整 job 失败
- public_path 冲突 catch 按约束名精确认领(postgres.js 的 constraint_name,
drizzle 包一层在 cause)——未来加第三唯一索引不误标,其余 23505 原样上抛
- 集成用例:不同 source_url 同旧 uploads 路径 → 后到不覆盖、issue 报告、
只留一行(mediaRegistered=1)
- 单测边界对拍:'<svg' 恰好收在 1024 字节窗口内(起点 1020)检出;起点
1021 被截断为 '<sv' → null
310 测试(308+2);typecheck/lint 三绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:56:16 +08:00 |
|
浅念
|
ed081ec477
|
feat(import): 媒体登记与安全校验
Plan 3 Task 4:media-writer(attachment 行三级对拍 + 内容行引用提取双事件消费)
+ magic-bytes 手写签名表(零新增依赖)。
- 三级对拍(前置事实 7):①uploads 相对路径清单精确命中 ②侧车 source_url→
file_path→清单实体(精确 miss 按文件名候选,多候选歧义不自动选全列 issue)
③missing 只进报告不插行(sha256 NOT NULL 库层防线)
- 魔数校验:命中实体读存储副本头部实际字节——SVG 检出 status=quarantined 不进
产物语义(引用不建 usage);未知签名 unsupported;扩展名声明 MIME 与检测不符
→ issue(按检测登记)
- usage 两阶段时序(WXR 文档序 items 先于 attachment):内容行提取引用 + 修订
锚点(依赖 content-writer 先处理同事件——Task 6 编排顺序契约),finish 统一
对 media_assets 反查(id→source_id / URL→source_url→public_path),顺序无关
- 悬空引用计数 mediaDanglingRefs 不静默(mini 203/204 钉死)
- counts 六键 media 前缀独占(勿复用 'skipped' 的键契约注记)
- 幂等:(site,source_url) 定向 onConflictDoNothing + usage 复合主键——重跑零增行
308 测试(296+6 单测+6 集成);typecheck/lint 三绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:38:10 +08:00 |
|