Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f21d972
新增:长直播任务基础设施
Aug 23, 2026
aa193c4
新增:实现长直播分层高光选片
Aug 23, 2026
bcaba93
新增:重构专业字幕编辑器
Aug 23, 2026
38fd603
新增:整合字幕审核与异步烧录
Aug 23, 2026
5bfef3e
修复:封住稳定 V1 数据安全风险
Aug 24, 2026
4eb82c1
文档:完成全项目工程体检
Aug 24, 2026
f5260c0
文档:更新 P0 整改后 Codemap
Aug 24, 2026
9ae8440
修复:收紧稳定 V1 路径与进程边界
Aug 24, 2026
8fabe12
修复:为 Workflow Job 增加执行代际隔离
Aug 24, 2026
a01f103
修复:完善发布执行隔离与幂等
Aug 24, 2026
a92f5c0
修复:收紧任务状态与切片原子性
Aug 24, 2026
1689d59
修复:增加流水线断点恢复
Aug 24, 2026
6b51bfb
修复:增加数据库迁移账本与索引保护
Aug 24, 2026
b3c1ae8
修复:恢复任务状态并精简新建流程
Aug 24, 2026
329d8a1
修复:收紧字幕批次与跨进程恢复
Aug 25, 2026
4d30e34
修复:统一 AI 与媒体处理失败边界
Aug 25, 2026
56f4d50
修复:收紧本地安全边界
Aug 25, 2026
3264ac4
修复:统一 AI 结果一致性与恢复
Aug 25, 2026
ae9f837
优化:重构工作台周统计面板
Aug 26, 2026
bf8e50c
修复:同步任务进度与运行日志
Aug 26, 2026
53b7cd6
优化:精简片段审核累计统计
Aug 26, 2026
6702c61
优化:重排发送中心 AI 文案操作
Aug 26, 2026
003f020
优化:补充全站克制动效
Aug 26, 2026
6e43b49
优化:移除工作台每日任务柱状图
Aug 26, 2026
5e46931
修复:兼容中文路径媒体预检
Aug 26, 2026
c3e52be
优化:调整抖音优先综艺选片提示词
Aug 26, 2026
a449c7b
优化:清理集成差异空白
Aug 28, 2026
f19c068
修复:恢复 Docker 页面冒烟
Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
634 changes: 634 additions & 0 deletions .codemap/codemap.html

Large diffs are not rendered by default.

182 changes: 182 additions & 0 deletions .codemap/codemap.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions .codemap/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"lang": "zh",
"project": "NiuMa Studio",
"subtitle": "牛马片场 · 本地 AI 高光生产后台工程体检",
"outputDir": ".codemap",
"htmlFile": "codemap.html",
"mdFile": "codemap.md"
}
1,086 changes: 1,086 additions & 0 deletions .codemap/modules.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,14 @@ jobs:
run: |
docker run --detach \
--name niuma-studio-ci \
--publish 8001:8001 \
--publish 127.0.0.1:8001:8001 \
--env DEMO_MODE=true \
--env DATA_DIR=/app/ci-data \
--env DATABASE_PATH=/app/ci-data/workflow.sqlite3 \
--env STORAGE_ROOT=/app/ci-tasks \
--env TASKS_DIR=/app/ci-tasks \
--env UPLOAD_TEMP_DIR=/app/ci-tasks/_temp \
--env NIUMA_TRUST_DOCKER_LOOPBACK_PROXY=true \
--env PUBLISH_SCHEDULER_ENABLED=false \
niuma-studio:ci

Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,9 @@ tasks/*

.DS_Store
Thumbs.db

# 本地工程审计产物
.scannerwork/
.coverage
coverage.xml
test-results.xml
53 changes: 53 additions & 0 deletions AUDIT_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# NiuMa Studio 全面工程体检任务书

## 背景

当前项目为 Windows 本地 AI 高光生产后台 V2.1.0。本轮联合使用 Codemap、Code Overhaul 与本地 SonarQube,回答项目为什么能运行、哪些部分可靠、哪些部分存在高风险技术债,以及应按什么顺序低风险整改。

## 目标

- 建立当前项目的功能模块图、依赖图、核心数据流与状态流。
- 审计架构、业务、代码、数据、稳定性、测试、安全、性能、可观测性和维护性。
- 运行现有安全测试、Lint、覆盖率与 SonarQube 静态扫描。
- 交叉验证三方结果并生成 `PROJECT_AUDIT.md`。

## 允许修改范围

- `.codemap/` 下的 Codemap 状态、配置和生成报告。
- `sonar-project.properties` 等仅用于本轮静态扫描的工程配置。
- `AUDIT_TASK.md`、`PROJECT_AUDIT.md`。
- 按项目规则追加 `DEVELOPMENT_LOG.md`、`NEXT_STEPS.md` 的审计记录。

## 禁止修改范围

- `app/`、`scripts/`、`tests/`、`prompts/` 中的生产逻辑和测试逻辑。
- 数据库 Schema、Migration、真实数据、浏览器登录态、发布队列和任务文件。
- `.env`、Cookie、Token、API Key、浏览器数据及任何秘密内容。
- 依赖版本、运行时行为、外部平台状态与远端系统。

## 已确定实现要求

- Codemap 以功能模块为单位,核心/高耦合模块独立评分,小型叶子模块可同一子任务内分别评分。
- Code Overhaul 使用 FULL AUDIT 模式,不在各章节暂停整改。
- SonarQube 优先复用现有本地容器;无法获得的指标必须明确写为“未取得”,不得估算成 Sonar 指标。
- Dead/Legacy/Mock/兼容代码只列出,不删除。
- 自动化测试不得连接真实 AI Provider 或触发真实投稿。

## 验收标准

- `PROJECT_AUDIT.md` 包含用户要求的全部章节、100 分健康度、Sonar 指标、P0-P3、Top 10、删除候选、暂不修改区和可独立回滚的整改路线图。
- 关键发现有 `file:line` 证据;Sonar 事实与人工审查结论明确区分。
- 记录实际测试命令、退出码、通过/失败/跳过数量和覆盖率。
- 最终 `git diff` 不包含生产代码、数据库、日志、缓存或敏感信息。

## 测试与扫描命令

- `.venv\Scripts\python.exe -m pytest`
- `.venv\Scripts\python.exe -m ruff check app tests scripts/seed_demo_data.py scripts/backup_restore.py scripts/backup_restore_runtime.py`
- `.venv\Scripts\python.exe -m coverage run -m pytest`(仅在 Coverage 可用时)
- Sonar Scanner(使用本地 SonarQube 与隔离的扫描配置)

## 返回格式

- 子代理返回精确命令、退出码、耗时与 `file:line` 证据。
- 主代理统一输出 `PROJECT_AUDIT.md`,并说明审计产物、测试结果、Git 提交、推送与 PR 状态。
304 changes: 304 additions & 0 deletions DEVELOPMENT_LOG.md

Large diffs are not rendered by default.

132 changes: 131 additions & 1 deletion NEXT_STEPS.md

Large diffs are not rendered by default.

936 changes: 936 additions & 0 deletions PROJECT_AUDIT.md

Large diffs are not rendered by default.

63 changes: 63 additions & 0 deletions STABILITY_P1_BOUNDARIES_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 稳定 V1 P1A 边界加固任务书

## 背景

P0 已封住测试误删、外键异常和永久删除半成功等数据安全风险。Codemap 与源码交叉审查仍确认三类高风险边界:任务目录可被恶意 `task_dir_name` 越界、并发任务可能获得同一目录、媒体接口可能把数据库中的任意本地路径作为文件响应;Windows 子进程终止也没有确认进程树真实退出。

## 目标

1. 所有任务目录解析都必须限定在 `TASKS_DIR`,拒绝绝对路径、盘符、`..` 与符号链接逃逸。
2. 新任务目录名使用原子目录预占,避免并发上传或重试复用同一目录。
3. 源视频继续支持 `STORAGE_ROOT` / `TASKS_DIR` / `ALLOWED_MEDIA_ROOTS`,但切片、字幕成片和封面响应必须绑定到当前任务及对应产物子目录。
4. 子进程终止必须确认退出;无法确认时显式失败,调用方不得继续按“已终止”处理。

## 允许修改范围

- `app/services/storage_service.py`
- `app/routers/media.py`
- `app/services/managed_process_service.py`
- 与本轮边界直接相关的测试
- `DEVELOPMENT_LOG.md`、`NEXT_STEPS.md`、Codemap 和本任务书

## 禁止修改范围

- 不改变 AI Provider、模型、登录或认证配置。
- 不改变真实投稿、字幕、切片业务语义。
- 不访问真实 NAS 文件,不触发真实第三方请求或投稿。
- 不修改数据库 Schema,不删除历史数据。
- 不删除遗留 `move_task_directory_to_trash`,且不改变其目标必须尚不存在的语义。

## 已确定实现要求

- 路径判断使用解析后的父子关系,不使用容易出现前缀碰撞的字符串判断。
- 任务目录名允许普通文件名中的 `~`,但拒绝绝对路径、盘符、空路径、根目录和任何 `..` 跳转。
- 原子分配通过 `mkdir(exist_ok=False)` 完成;只有任务创建链显式启用预占。
- 数据库读取失败不得静默伪装为“无任务目录”。
- 切片只允许 `05_clips`(兼容旧 `clips`),字幕成片只允许 `06_subtitled`;封面只允许 `07_covers`。
- 对旧 C 盘任务目录只保留受控兼容读取,不扩大到任意路径。
- Windows `taskkill` 的超时、启动失败、非零退出码和退出确认失败均需有明确行为;若进程已并发退出可视为成功。

## 验收标准

- `..\\outside`、绝对路径、盘符和符号链接逃逸不能创建或读取任务目录。
- 两个并发同名目录预占获得不同名称,不发生文件覆盖。
- 数据库中指向任务目录外的切片/字幕路径返回 404;合法任务产物仍可读取。
- 外部白名单源视频读取保持兼容。
- 模拟 `taskkill` 成功、并发退出、非零失败、超时均有确定测试。
- 定向测试、全量测试、Ruff 和 Compileall 通过。

## 测试命令

```powershell
pytest -q tests/test_storage_boundaries.py tests/test_managed_process_service.py tests/test_media_storage_lifecycle.py
pytest -q
ruff check app tests scripts
python -m compileall -q app scripts
```

## 返回格式

- 修改文件与行为边界。
- 测试命令、通过数量与失败证据。
- 对外部原片、遗留目录和现有调用方的兼容结论。
- Commit、分支、Push、PR 状态和下一轮 P1 风险。
87 changes: 87 additions & 0 deletions STABILITY_P1_DATABASE_MIGRATION_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# P1.3c 数据库迁移账本与唯一索引 Fail-Closed

## 背景

当前 `init_db()` 通过表结构探测、`ALTER TABLE` 和 `executescript()` 兼容历史数据库,但没有可查询的迁移版本账本。更高风险的是 `_create_indexes()` 会先删除发布任务的活动唯一索引,再静默吞掉所有索引创建异常;一旦重建失败,应用仍会启动并允许重复活动发布任务进入数据库。

## 本轮目标

1. 建立最小、可扩展的 `schema_migrations` 迁移账本。
2. 每条新迁移记录稳定版本、名称、校验和与完成时间。
3. 版本相同但校验和变化时拒绝启动,避免迁移定义被静默改写。
4. 发布活动任务唯一索引采用“先建立并验证新版索引,再删除旧索引”的顺序。
5. 索引缺失、定义漂移、重复数据或 SQLite 异常时明确失败,不再静默继续运行。
6. 迁移执行与账本写入位于同一 SQLite 事务中;失败不写成功记录。
7. 已有数据库在 P1.3c 首次写入前创建 SQLite Online Backup;备份失败则不开始迁移。

## 允许修改

- `app/db/database.py`
- 新增与本轮直接相关的隔离数据库测试
- `DEVELOPMENT_LOG.md`
- `NEXT_STEPS.md`
- `PROJECT_AUDIT.md`
- `.codemap/*`
- 本任务说明

## 禁止修改

- 不直接运行或迁移正式 `workflow.sqlite3`。
- 不删除、合并或自动修复正式库中的历史发布记录。
- 不修改业务状态机、发布调度、Provider、Worker 或页面逻辑。
- 不引入 Alembic 或其他新依赖,不重写全部历史兼容迁移。
- 不处理 P1.4 Provider 超时或 P1.5 Secret/Auth。

## 已确定实现要求

### 迁移账本

- `schema_migrations.version` 为主键,并保存 `name`、`checksum`、`applied_at`。
- P1.3c 及后续正式 Schema 变更必须通过有序迁移注册表执行。
- 已应用迁移必须校验 checksum 和数据库不变量;不能只看到版本号就假定成功。
- 账本只记录完整成功的迁移,不把失败尝试伪装成已应用。
- 旧的列探测兼容逻辑本轮保留,并明确视为 pre-ledger compatibility,不宣称已经完成全面 Alembic 化。

### 唯一索引

- 新版索引使用独立版本化名称,约束同一 `output_clip_id + platform + publish_mode` 只能存在一条活动发布任务。
- 活动状态继续包括 `DRAFT`、`WAITING`、`SCHEDULED`、`PUBLISHING`、`NEED_REVIEW`。
- 新索引创建和定义验证成功前,不删除旧版保护索引。
- 发现活动重复数据时拒绝迁移,并返回不包含 Secret 的诊断信息;不擅自决定保留或取消哪条发布记录。
- 已应用迁移启动时仍验证索引存在、唯一性和定义,防止手工删索引或 Schema 漂移后继续运行。

### 事务与并发

- 每条账本迁移通过 `BEGIN IMMEDIATE` 串行化。
- Schema 修改、验证和账本写入同事务提交;任一步失败全部回滚。
- 两个本地进程同时初始化同一库时,后到进程应读取已完成账本,而不是重复写入或吞掉锁错误。

## 验收标准

1. 新建隔离库初始化后恰有一条 P1.3c 迁移记录,重复初始化不新增记录。
2. 新版唯一索引存在且旧版索引已在成功后移除。
3. 迁移 checksum 漂移时明确拒绝启动。
4. 已应用迁移的索引缺失或定义错误时明确拒绝启动。
5. 活动重复数据导致索引无法建立时,启动失败、迁移不入账、数据不被自动改写。
6. 模拟新版索引验证失败时,旧版索引仍存在,证明切换顺序和回滚有效。
7. 索引列表中的其他 SQLite 异常不再被静默吞掉。
8. 定向测试、完整 Pytest、Ruff、Compileall 通过;测试只使用临时数据库。
9. 正式数据库文件的大小、mtime、hash 均不因本轮验证改变。

## 测试命令

```powershell
.\.venv\Scripts\python.exe -m pytest -q tests/test_schema_migration_ledger.py tests/test_database_backup_service.py tests/test_publish_scheduler_state_machine.py tests/test_job_fencing.py tests/test_long_live_foundation.py
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m ruff check app tests
.\.venv\Scripts\python.exe -m compileall -q app tests scripts
```

## 返回格式

- 迁移账本与唯一索引切换方式。
- 失败/漂移/重复数据的 fail-closed 证据。
- 正式数据库未被修改的证据。
- 定向与全量验证结果。
- 仍保留的 pre-ledger 历史迁移边界。
- Commit、分支、PR 与下一独立轮次。
77 changes: 77 additions & 0 deletions STABILITY_P1_FENCING_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# 稳定 V1 P1B 执行代际 Fencing 任务书

## 背景

P0 与 P1A 已封住真实数据、路径和进程终止边界。剩余最高风险集中在异步执行代际:旧 Workflow Worker 在 lease 过期并被接管后仍能写进度或终态;旧 Publish execution 也能覆盖新 claim;Windows Publish Worker 对同一 execution id 会再次调用真实 Publisher。

## 目标

1. Workflow Job 每次 claim 生成唯一 `lease_token`,所有 Worker 写回必须同时匹配 owner + token。
2. 旧子进程在执行副作用前验证租约;失去租约后不能更新 checkpoint、进度或终态。
3. 存活但达到最大尝试次数的 Worker 不得被其他 Worker 提前判为失败。
4. Publish Job 使用现有 `execution_id` 作为代际 token,旧执行不能覆盖新 claim。
5. Publish Worker 对同一 execution id 幂等;路径标识只能是安全的单段 ID。

## 分阶段范围

### P1B.1 Workflow Job

- `app/db/database.py`
- `app/services/job_service.py`
- `app/services/job_worker.py`
- `app/services/job_worker_process.py`
- 必要的 Pipeline/转写/字幕 heartbeat 调用
- `tests/test_job_fencing.py` 及相关既有测试

### P1B.2 Publish Scheduler / Worker

- `app/services/publish_repository.py`
- `app/services/publish_scheduler.py`
- `app/services/publish_executor.py`
- `scripts/publish_host_worker.py`
- `app/services/publishers/browser_runtime.py`
- `app/services/publishers/worker_client.py`
- 发布 fencing/幂等测试

## 禁止范围

- 不改变 AI Provider、模型、账号、Token、Cookie 或 Chrome Profile 内容。
- 不触发真实 AI、真实投稿、登录或平台验证。
- 不删除任务、发布记录、execution journal 或历史证据。
- 不引入消息队列、微服务或新数据库。
- 不自动合并 PR,不强推。

## 数据库变化

- 只为 `workflow_jobs` 新增可空 `lease_token TEXT`。
- 不重建表、不删除列、不改外键。
- 每次 claim 写入新随机 token;release/retry/终态清空 token。
- 正式库应用迁移前必须创建 SQLite Online Backup 并确认 `quick_check=ok`;存在旧 running 且 token 为空时必须停止并人工处理,不能静默视为有效租约。

## 验收标准

- Worker A 过期、Worker B 接管后,A 的 heartbeat/progress/checkpoint/completed/failed/cancelled/release 全部被拒。
- `already_claimed` owner/token 不匹配、lease 过期或状态不正确时,不调用任何业务执行器。
- running 且 lease 有效的任务达到 max_attempts 后仍保持 running;过期后才失败。
- execution A 不能覆盖 execution B 的 Provider 结果、phase 或终态。
- 并发 `repair_and_publish` 只创建一个替代任务。
- 同 execution id 重试不再次调用 Publisher;不同身份复用同 id fail-closed。
- 定向、全量、Ruff、Compileall 通过;真实发布调用次数为 0。

## 测试命令

```powershell
pytest -q tests/test_job_fencing.py tests/test_job_queue.py tests/test_long_live_foundation.py
pytest -q tests/test_publish_fencing.py tests/test_publish_scheduler_state_machine.py tests/test_publish_worker_client.py
pytest -q
ruff check app tests scripts
python -m compileall -q app scripts
```

## 返回格式

- Schema 变化、备份和兼容处理。
- 旧执行被拒的 SQL/测试证据。
- 全量测试与静态检查结果。
- Commit、分支、Push、PR 状态。
- 剩余状态机、半提交和外部调用风险。
Loading
Loading