浅念
|
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 |
|
浅念
|
99c07906cd
|
docs(plan): P3 Task 3 勾选 + Task 6 编排义务六项
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:20:08 +08:00 |
|
浅念
|
fe72df3afa
|
chore(import): unsupported/failed 分项计数与键契约 JSDoc;NULL-entry 缝注释;lineage 语义注记
审查 cheap riders 四项:handleUnmappable 分项 unsupportedRecords/
failedRecords(按事件计——拆分只在分派点可知,Task 6 无从重derive,测试
对拍两键);ImportPipelineOutcome.counts 键契约注记(跨写入器扁平全局
命名空间、同名 CLOBBER 不求和、各键归属声明、Task 4 勿复用 'skipped');
六列 NULL-entry 已知死角缝注释(23505 → Task 6 收编);态 1 checksum-diff
的 import_job_id lineage 语义注记(source_records 留建行 job、新 job 记
content_revisions)。296 全绿;typecheck/lint 通过。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 18:19:37 +08:00 |
|
浅念
|
2b61431da8
|
feat(import): 内容稳定身份写入
Plan 3 Task 3:content-writer(row→entry/locale/revision/source_record,
checksum skip 幂等三态)。checksum 按前置事实 6 公式精确实现(canonicalJson
六输入域 + sha256;rawLocation 排除、版本三常量入、status 入、sourceUrl 经
route_source_values 入);六列快照行身份 + 五列内容身份(跨快照复用 entry,
permalink 变化产新修订不建新 entry);attachment/unsupported/error 只记
source_records(前置事实 11/12,error 无 postId 以 rawLocation 回退不硬造);
导入全程不触 published 指针(ADR-010)。term-writer JSDoc 补 null-id 建行
不计入 autoCreatedTerms 注脚(Task 2 遗留)。
测试:tests/integration/import-content.test.ts 7 用例(mini 全链对拍/同快照
skip/跨快照稳定身份/内容变化/ permalink 变化/unsupported+error/locale 校验),
296 全绿;typecheck 四段链/lint 通过。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 17:09:06 +08:00 |
|
浅念
|
24220c5ee9
|
docs(plan): P3 Task 2 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 16:50:12 +08:00 |
|
浅念
|
8485c51d59
|
fix(import): term 边缘欠报闭合(null-id 双序等价/同 slug 双 id 报告);handleEvent 分派形状
审查修复:
- null-id wp:term 双序等价:seen 分支同样报缺 term_id issue;自建行 name-only
收编(UPDATE name 为权威名、source_id 不动),term 先行/row 先行终态 name
与 issue 双序一致(测试钉死);真实 id 行不覆盖(first-wins)
- 同 slug 双 term_id:镜像条件显式报告(保留先到、跳过后到 + rawLocation),
文档序 first-wins 策略 JSDoc 钉死(测试含关联绑保留行)
- 冲突重查未命中由 found[0]! 改显式 throw(taxonomy/term 两处,含键上下文)
- adoptTerm catch 注明 ctx.db 直连约定(事务内 25P02 连锁风险——Task 6 包
事务时须重估);收编撞唯一约束路径补测试(自建行原样保留 + issue)
- 重构:内部件抽为 createTermEventHandler({handleEvent, finish}) 可分派形状
(Task 6 单消费方拉流分派、无 tee 的编排意图),createTermWriter 为自消费
整流便捷壳
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 16:44:25 +08:00 |
|
浅念
|
191c275713
|
feat(import): term 物化与缺失自建
Plan 3 Task 2:createTermWriter 管道写入器——双源物化分类域。
- wp:term 事件:taxonomies(key→object_type 映射 + public_base_path 前置事实 9
常量)+ terms(source_id=term_id 字符串)
- row 的 taxonomyRefs miss 时自建(source_id=auto:<nicename>、slug=nicename;
phase2-smoke 实证真实 WXR 的 wp:term 表缺 category/post_tag 整域);同 nicename
多次引用只建一条(内存 (taxonomy,slug) 索引 + UNIQUE 兜底)
- 单遍流式 + 收编:WXR 文档序 items 先于 wp:term——row 先到自建、wp:term 后到
就地 UPDATE 扶正 source_id/name,两种顺序终态一致(测试钉死顺序无关性)
- content_terms:is_primary 每 (entry, taxonomy) 首个 true 余 false(WP 单主分类
近似);row 无 content entry → term 仍物化、关联跳过 + issue(禁静默)
- ctx 加法扩展 events: AsyncIterable<AdapterEvent>(测试手构注入,Task 6 接真流)
- Task 1 遗留两行:ImportErrorCode 补 REPORT_WRITE_FAILED、ctx.db 事务边界 JSDoc
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 16:19:00 +08:00 |
|
浅念
|
2d57c3c814
|
docs(plan): P3 Task 1 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 16:00:14 +08:00 |
|
浅念
|
eb188da5c2
|
fix(import): 复用口径忠实化;管道 Outcome 契约与 succeeded_with_issues;报告写入时序;stale 警告
评审修复(Plan 3 Task 1 复审):
- 复用路径只返回 job 锚定字段(jobId/status/reused/siteId/mapping_version/
report_path),快照/版本块仅在非复用时解析返回——复用结果不再回显编造数据
- ImportPipeline 契约钉死:返回 Promise<ImportPipelineOutcome>
({ counts, issues });服务按"累加器 ⊕ 返回值"合并(counts 同键返回值
覆盖、issues 累加器在前),issues 非空 → succeeded_with_issues;
ctx.report 即累加器(管道抛错时部分产出仍入报告)
- 报告时序:mkdir + tmp 写入 + rename 先于终态行更新——report_path 落库
即文件存在;写失败 → failed(REPORT_WRITE_FAILED),不挂悬空路径
- CLI 复用命中非终态(queued/running)→ 崩溃残留警告(重试需显式换 --key)
- 管道抛 ImportError 保留原 code 入 error_code,summary 冠 [pipeline]
- 确定性 23505 探针:未提交孪生 job 行事务内持唯一键触发真实 PG 唯一
冲突 → 败者复用既有 job
- 报告补 idempotencyKey / attempt 字段
- 计划文档 Task 6 增补 stale 回收决策项(ADR-017)
测试 282 通过(279 + 3:Outcome 合并/ImportError 前缀/23505 探针);
typecheck 四段链 + lint 全绿。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 15:56:00 +08:00 |
|
浅念
|
0e8b2b5356
|
feat(import): job 骨架与生命周期
Plan 3 Task 1:sf import 命令骨架 + import_jobs 生命周期(空管道,Task 6 接真实管道)。
- import.service.ts(零装饰器):createImportJob——站点/快照解析(缺省按 (connection,
kind='wxr') 选最新;三快照绑定按前置事实 13 记入报告,job 行不扩列)、幂等建行
(默认 key=site+wxr快照+三语义版本;重复提交复用既有 job 不重跑,并发撞唯一约束
重查收敛)、状态推进 queued→running→succeeded/failed(attempt/started_at/finished_at/
error_code/error_summary)、报告落 artifacts/import/<jobId>/reports/import.json
(全四版本块:adapter/mapping/sanitizer/parser;job 行落 mapping_version)
- 可预期错误带 code:SITE_NOT_FOUND / SNAPSHOT_NOT_FOUND / NO_WXR_SNAPSHOT /
PIPELINE_FAILED——解析期失败零 job 行
- adapter 事件加法式补 postId(前置事实 12):unsupported/error 事件可选携带
String(postId),缺失时键缺席不硬造 source_id;row 事件与报告聚合零影响、不触发版本 bump
- canonicalJson 提取至 apps/api/src/common/canonical.ts 共享导出(前置事实 6),
register 侧改 import 零行为变更(既有清单哈希测试守护)
- sf CLI + import 命令(--site/--snapshot/--key/--connection),输出 job 摘要与版本块
- 测试:tests/integration/import-job.test.ts(5 例:生命周期观察/最新快照解析/幂等复用
与并发收敛/可预期失败零落行/failed 路径)+ adapter postId 3 例 + canonical 单测 6 例
(265→279 全绿);typecheck 四段链/lint 绿;临时库 CLI 冒烟(register→import→复用)通过
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 15:30:42 +08:00 |
|
浅念
|
e52a2eb3e4
|
docs(plan): P3 Task 0 勾选
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 15:13:09 +08:00 |
|
浅念
|
a185254e19
|
chore(scripts): 侧车导出加固——site-id UUID 校验与 audit 非 CDATA 匹配
评审两条非阻塞加固:--site-id 拼入 SQL 前过 UUID 形态白名单(非 UUID 拒绝并
明确报错);--audit 的 attachment_url 抽取正则同时匹配 CDATA 与裸文本两形态。
对真实数据重跑数字不变(859 条 / 855 对 836 命中,输出哈希一致)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 15:12:41 +08:00 |
|
浅念
|
25dcdf0a4d
|
docs: 路线 V1.1——迁移优先快线为主(用户拍板最快见效),蓝图后移至迁移 MVP 后
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 15:04:51 +08:00 |
|
浅念
|
a227cfac49
|
feat(source): 媒体映射侧车导出与登记
Plan 3 Task 0(评审 Issue 1):旧 cms 库 media_assets 的 source_url→file_path
映射只读导出为侧车 JSON(859 条,覆盖率对照 WXR 855 attachment_url:精确命中
836 / 归一命中 0 / 未命中 19,97.8%),register 新增 --media-map 输入通道
(kind=manual_url_list 快照,形状校验 INVALID_MEDIA_MAP,metadata 含条目数,
幂等复用)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-21 14:42:32 +08:00 |
|