{
  "slug": "preview-first-batch-safety",
  "publishedAt": "2026-08-29",
  "modifiedAt": "2026-08-29",
  "productionCommit": "c35d0c7a7c3515efe56c7e7f653ecc30127ce057",
  "evidenceType": "source-backed-production-behavior",
  "sources": [
    {
      "path": "components/RenamerTool.tsx",
      "blobSha": "c29930e577d34a07c05c50f5659986a00c4e6fd6"
    },
    {
      "path": "components/ImageConverterTool.tsx",
      "blobSha": "afeae88293d352851867a4274bfa9bc170680244"
    },
    {
      "path": "lib/file-names.ts",
      "blobSha": "3add8381f7ab8c6d5c189466667465480ef77fd2"
    }
  ],
  "methodology": {
    "zh": "依据绑定生产 commit 的实际批量改名、图片转换与输出命名源码整理。这里记录的是可从当前生产实现核对的防错行为，不把 UI 提示扩大解释成零风险保证。",
    "en": "Compiled from the batch-renaming, image-conversion and output-naming source pinned to the production commit. It records safeguards that can be checked in the current implementation without stretching UI protections into a zero-risk guarantee."
  },
  "assertions": [
    {
      "id": "rename-before-after-preview",
      "label": {
        "zh": "执行前显示原文件名 → 新文件名",
        "en": "Old-name → new-name preview before execution"
      },
      "effect": "preview",
      "sourcePaths": [
        "components/RenamerTool.tsx"
      ],
      "evidence": {
        "zh": "改名工作区为每个文件计算并显示原文件名、新文件名、警告与错误，让用户在生成 ZIP 前逐项检查结果。",
        "en": "The rename workspace computes and displays the original filename, proposed filename, warnings and errors for each file so the batch can be reviewed before ZIP creation."
      }
    },
    {
      "id": "duplicate-output-blocking",
      "label": {
        "zh": "同批次重复输出名会阻止执行",
        "en": "Duplicate output names block the batch"
      },
      "effect": "blocks_run",
      "sourcePaths": [
        "components/RenamerTool.tsx"
      ],
      "evidence": {
        "zh": "输出名称按不区分大小写的方式检查重复；同批次冲突会成为阻断错误，而不是等 ZIP 生成后才发现覆盖风险。",
        "en": "Proposed output names are checked case-insensitively for duplicates. A collision becomes a blocking error instead of waiting until ZIP creation to reveal the conflict."
      }
    },
    {
      "id": "unsafe-filename-blocking",
      "label": {
        "zh": "常见不安全文件名条件会阻止执行",
        "en": "Common unsafe filename conditions are blocking"
      },
      "effect": "blocks_run",
      "sourcePaths": [
        "components/RenamerTool.tsx"
      ],
      "evidence": {
        "zh": "当前检查包括空名称、斜线/反斜线、控制字符、常见保留符号、结尾空格或句点、Windows 保留名，以及超过当前 180 字符上限的输出名。",
        "en": "Current checks cover empty names, slash/backslash, control characters, common reserved symbols, trailing spaces or periods, Windows reserved names, and output names beyond the current 180-character limit."
      }
    },
    {
      "id": "extension-loss-advisory",
      "label": {
        "zh": "扩展名丢失会警告，但允许用户决定",
        "en": "Extension loss is warned, not forcibly blocked"
      },
      "effect": "warning_only",
      "sourcePaths": [
        "components/RenamerTool.tsx"
      ],
      "evidence": {
        "zh": "如果原文件有扩展名而拟议输出名没有扩展名，工作区给出提醒；它保持为警告，因为用户可能有意改变或移除扩展名。",
        "en": "If a source file has an extension but the proposed output does not, the workspace warns the user. It remains advisory because removing or changing an extension can be intentional."
      }
    },
    {
      "id": "blocking-errors-disable-run",
      "label": {
        "zh": "存在阻断错误时执行入口不可用",
        "en": "Blocking errors disable execution"
      },
      "effect": "blocks_run",
      "sourcePaths": [
        "components/RenamerTool.tsx"
      ],
      "evidence": {
        "zh": "改名批次存在红色阻断错误时，生成下载 ZIP 的执行入口保持禁用，先要求解决命名冲突或非法名称。",
        "en": "When the rename batch contains blocking errors, the action that creates the downloadable ZIP remains disabled until the naming conflict or invalid output is resolved."
      }
    },
    {
      "id": "rename-preserves-originals",
      "label": {
        "zh": "改名生成新 ZIP，不覆盖或删除原文件",
        "en": "Renaming creates a new ZIP without overwriting originals"
      },
      "effect": "preserves_originals",
      "sourcePaths": [
        "components/RenamerTool.tsx"
      ],
      "evidence": {
        "zh": "执行时使用浏览器中已有的原 File 对象，把它们以拟议新名称写入新的 ZIP；FileNest 不直接覆盖或删除用户设备上的源文件。",
        "en": "Execution uses the existing browser File objects and writes them into a new ZIP under the proposed names. FileNest does not directly overwrite or delete the source files on the user's device."
      }
    },
    {
      "id": "image-source-thumbnail-preview",
      "label": {
        "zh": "批量图片可逐张查看源图缩略图",
        "en": "Batch images expose per-file source thumbnails"
      },
      "effect": "preview",
      "sourcePaths": [
        "components/ImageConverterTool.tsx"
      ],
      "evidence": {
        "zh": "图片批次为加入的源图建立浏览器 Object URL，并在多图批次中显示可点击缩略图，让用户处理前切换检查每张源图。",
        "en": "Image batches create browser Object URLs for the added source files and show clickable thumbnails in multi-image batches so each source image can be inspected before processing."
      }
    },
    {
      "id": "image-output-name-deduplication",
      "label": {
        "zh": "图片结果重名会确定性追加编号",
        "en": "Image output name collisions get deterministic suffixes"
      },
      "effect": "deduplicates_output",
      "sourcePaths": [
        "components/ImageConverterTool.tsx",
        "lib/file-names.ts"
      ],
      "evidence": {
        "zh": "图片输出使用同批次已用名称集合做不区分大小写的去重；发生冲突时依序生成 name (2)、name (3) 等名称，避免 ZIP 中出现同名结果。",
        "en": "Image outputs use a case-insensitive set of names already used in the batch. Collisions are resolved deterministically as name (2), name (3), and so on to avoid same-name results in the ZIP."
      }
    }
  ],
  "limitations": {
    "zh": [
      "这份证据当前只覆盖批量改名与图片批次的预览、命名与原文件保护机制，不代表 FileNest 每一个工具都使用完全相同的安全流程。",
      "文件名校验能发现结构性冲突和常见非法名称，但无法判断每个项目里的业务语义是否正确，例如编号顺序是否符合用户真实意图。",
      "扩展名丢失属于提醒而不是硬性阻断，因为用户可能有意改变扩展名；执行前仍需要人工检查。",
      "图片缩略图是加入批次的源图预览，不是每一种转换、压缩、增强结果在执行前的最终像素级保证。",
      "本报告不测试浏览器/设备兼容矩阵、性能、内存峰值或超出当前工具限制的大批次。浏览器下载与 ZIP 生成仍可能受设备资源影响。",
      "这是绑定生产 commit 的快照；如果当前工具页与旧证据冲突，应以当前工具页为准并更新本报告。"
    ],
    "en": [
      "This evidence currently covers preview, naming and original-file protections in batch renaming and image batches; it does not claim every FileNest tool uses the identical safety flow.",
      "Filename validation catches structural collisions and common invalid names, but it cannot decide whether project-specific naming semantics are correct, such as whether a sequence matches the user's real intent.",
      "Extension loss is advisory rather than a hard block because a user may intentionally change an extension; human review before execution still matters.",
      "Image thumbnails preview the source files added to the batch. They are not a pixel-level pre-execution guarantee of every conversion, compression or enhancement result.",
      "This report does not test browser/device matrices, performance, peak memory or batches beyond current tool limits. Browser downloads and ZIP creation can still be constrained by device resources.",
      "This is a snapshot pinned to a production commit. If a current tool page conflicts with older evidence, prefer the current tool page and update this report."
    ]
  }
}
