Files
mindfulness/spec_kit/Text Wrap/modules/core-contract/plan.md
2026-02-10 11:39:33 +08:00

4.8 KiB
Raw Blame History

core-contract技术计划

1. 计划目标

基于 spec.md设计说明文档/文档换行算法.md v1.2.1,落地跨端一致的“基础口径与契约”,为后续断点生成、搜索与评分提供稳定输入与确定性工具,确保:

  • EN/TC 的 token 索引体系 与断点 pos 语义固定
  • 文本 可重组:任意 [start..end) 区间可稳定还原为行文本
  • EN 关键词命中规则严格为 全词等值匹配(避免 substring 误伤)
  • 空白归一化策略可配置但默认一致(推荐 NORMALIZE
  • 提供可复用的 确定性比较工具(用于 breaks 字典序/tieKey 比较)

2. 默认技术决策(本计划采用)

  • 空白策略:默认 whitespacePolicy=NORMALIZE
    • 行为:折叠连续空白为 1 个空格、去首尾空白
    • 并在 meta后续模块中打点 hadMultiWhitespace(本模块先预留布尔返回位)
  • EN tokenize:仅生成 WORD token不生成 SPACE token以空白分隔标点按“极简派”保留在词内
  • TC tokenize:本模块只定义接口,具体分割由 grapheme-segmentation 提供
  • EN 关键词命中lowercase → strip 两端常见标点 → 等值比较,禁止 contains/substring
  • 确定性比较breaks 字典序比较按“逐项比较 + 公共前缀相同则更短者更小”

3. 目录与产物

本子模块目录:

  • spec_kit/Text Wrap/modules/core-contract/spec.md
  • spec_kit/Text Wrap/modules/core-contract/plan.md(本文)

建议未来代码落位(实现阶段再定,不在本计划强制):

  • client/src/features/textWrap/core/(或 client/src/utils/textWrap/

4. 设计与实现要点(按落地顺序)

4.1 文本预处理normalizeWhitespace

实现 normalizeWhitespace(text) -> { normalizedText, hadMultiWhitespace }

  • 规则:
    • 把任意连续空白(空格/制表/换行等)折叠为单个空格
    • 去除首尾空白
  • 注意:
    • 该规范会改变输入文本;必须作为“算法契约”的一部分固定下来
    • 若后续产品需要保留原始空白,则走 PRESERVE 分支并输出 rawSeparators(见 4.3

4.2 EN tokenizeword tokens极简派

实现 tokenizeEN(normalizedText) -> tokens[]

  • 以空格分隔生成 token
  • token 只包含 WORD标点视为词内字符例如 tired.Wait...hello—worlddon't 都是单 token
  • 输出 token 的 text/start/endstart/end 为原始或 normalized 的字符区间,需固定口径;建议以 normalizedText 为基准)

4.3 文本重组joinTokens

实现 joinTokens(tokens, start, end, separators?) -> string

  • EN 默认:使用单空格 " " join [start..end) 的 token.text
  • whitespacePolicy=PRESERVE
    • 需要 rawSeparators[i] 表示 tokens[i] 与 tokens[i+1] 间的原始分隔符
    • 重组时按 separators 拼接(本计划仅定义接口与行为)

4.4 EN 关键词命中normalizeENKeyword + matchENKeyword

实现:

  • normalizeENKeyword(tokenText) -> string
    • lowercase
    • strip 两端常见标点(集合需配置化并全端一致,默认参考文档:, . ! ? : ; " ' … — ( ) [ ] { }
  • matchENKeyword(tokenText, keyword) -> boolean
    • normalizeENKeyword(tokenText) === normalizeENKeyword(keyword)
    • 禁止 includes/contains 类 substring 命中

4.5 断点/区间的索引契约

固化约定(后续模块必须复用,不得自行发挥):

  • token 索引:tokens[0..N-1]
  • 断点 pos:位于 token 边界,切分为 [0..pos)[pos..N)
  • 行区间:[start..end) 表示 tokens[start] ... tokens[end-1]

5. 回归用例与验证方式

5.1 必测示例EN

  • "I am so tired" → tokens=[I, am, so, tired]
    • pos=2"I am" / "so tired"
  • 标点极简派:
    • "tired." 为单 token
  • 关键词命中:
    • keyword="but""but," 命中;"rebuttal" 不命中

5.2 确定性检查

  • 同一输入在同一配置下多次调用:
    • normalizedTexttokens[]joinTokens()matchENKeyword() 输出完全一致

6. 风险与规避

  • start/end 索引口径漂移:若不同端选择以原始 text 或 normalizedText 计数,可能导致 span 对不齐
    • 规避:本模块明确 start/end 以 normalizedText 为准(或在实现阶段统一选择一种并写入 README/注释)
  • 标点集合不一致strip 集合若跨端不同会导致命中差异
    • 规避:将 punctuationStripSetEN 写入配置并版本化,禁止散落常量

7. 完成定义DoD

  • core-contract/spec.md 中定义的输入/输出与验收条目均有可运行的最小实现或可验证的约束说明
  • EN tokenize / 空白归一化 / 关键词命中 / breaks 字典序比较口径写清楚且可复现
  • 关键示例用例可在本地/CI 以单元测试或脚本方式验证(实现阶段落地)