Skip to content

Add math-script match options to insertion anchors - #115

Open
kiki830621 wants to merge 1 commit into
mainfrom
codex/math-script-match-options
Open

Add math-script match options to insertion anchors#115
kiki830621 wants to merge 1 commit into
mainfrom
codex/math-script-match-options

Conversation

@kiki830621

Copy link
Copy Markdown
Member

Summary

  • expose match_options.math_script_insensitive on insertion text-anchor tools
  • parse match options into OOXMLSwift AnchorLookupOptions for after_text / before_text
  • add coverage for exact default behavior, H₀/H0 bidirectional matching, schema exposure, and invalid option type rejection
  • temporarily depend on Add math-script-insensitive anchor lookup ooxml-swift#38 branch until that PR is merged/released

Validation

  • swift test --filter Issue90MathScriptMatchOptionsTests
  • swift test --filter Issue61InsertParagraphAnchorsSmokeTests --filter Issue61InsertEquationAnchorsSmokeTests --filter AnchorDXConsistencyTests

Depends on PsychQuant/ooxml-swift#38.
Refs #90

@kiki830621

Copy link
Copy Markdown
Member Author

Verify Report — PR #115

Engine

Agent Team (3 Claude reviewers: requirements / logic / devil's-advocate) + Codex CLI (gpt-5.5 xhigh)
Note: Security + Regression skipped — 純 wiring opt-in flag、無新依賴入口;regression 機械檢驗併入主對話。

Aggregate

PASS pending cross-repo dep — 1 P1 (cross-repo branch dep), 4 P2 follow-up, ~10 P3

四個獨立 reviewer 都判定 #90 的核心 Path B 設計 FULLY addressed

  • ✅ Path B 採用:bidirectional matching at lookup-time(非 Path A visibleText mutation),未動 MathSubSuperScript.visibleText
  • ✅ 4 個 insertion call sites 全部 wired:insert_paragraph (Server.swift:6832)、insert_image_from_path (8125)、insert_equation (9014)、insert_caption (12456)
  • ✅ Default behavior 保留:omit match_options / omit math_script_insensitive.exact 維持向下相容
  • ✅ 雙向測試:H₀ → H0 (test:51) + H0 → H₀ (test:88)
  • ✅ Strict type rejection 完備:"true" string、int、null、[]42 都正確 reject
  • ✅ Lib API signature match:AnchorLookupOptions from ooxml-swift branch 09d0e6e9 與 PR 用法一致
  • swift test --filter Issue90MathScriptMatchOptionsTests --disable-sandbox (with /tmp cache) → 5 tests, 0 failures

但 Codex + DA 共同指出 Unicode 覆蓋缺口(特別是 issue #90 body 明列的 ),且 Package.swift 仍 pin 到 branch dep 是合併阻擋。

Scope coverage

PR refs: #90
Verified scope: #90


#90 — math_script_insensitive Path B (P3 enhancement)

Coverage: FULLY addressed for the core H₀/H0 case + 4 insertion tools wiring。但兩個 issue body 明列的 anchor 形態(α₁)有部分未涵蓋。

# Severity Finding Source location
1 P1 🛑 Cross-repo branch dependencyPackage.swift:9 暫指向 branch: codex/math-script-anchor-options(ooxml-swift#38 仍 OPEN)。雖然 Package.resolved 有 pin commit 09d0e6e9,但 branch dep 仍是合併 hygiene blocker:swift package update 會 surprise users;ooxml-swift#38 review 中若改 API 會立即 break;force-push 也會破壞 pin。Merge gate: ooxml-swift#38 merged + tagged → 把 branch: 改回 from: "0.22.0"(或新 tag)。PR description 已明示,PR 為 draft。 Package.swift:9, Package.resolved:44
2 P2 Unicode subscript 覆蓋有具體缺口(issue #90 自身列出的 X̄ 沒處理):lib 的 mathScriptVariantMap 是手動列舉式,漏掉:(a) combining macron U+0304 — issue body 明確列 X̄ = X + ̄ 為典型 anchor pattern;(b) Greek subscripts U+1D66..U+1D6A (ᵦᵧᵨᵩᵪ) — 統計/物理論文 ΣᵦΠᵧ 等常用標記。issue example α₁ 應該 work(α + U+2081 數字下標)但 的 combining mark case 0-match 是核心 use case 仍 broken。 packages/ooxml-swift/.../InsertLocation.swift:75-90 + 跨 repo
3 P2 U+2094 (subscript schwa)缺漏。Codex 指出若驗收標準是「完整 U+2090..U+209C」,這裡還不完整。罕見 use case 但行為不一致。 InsertLocation.swift:75-90
4 P2 缺 negative test:所有 test 只測「應 match + default exact」,沒固化「flag 開但不該 match」case,例如 H₂H₃X 等。一旦未來 over-fold 出現假陽性,現有 test 全 pass。 Issue90MathScriptMatchOptionsTests.swift
5 P2 Discoverability 為零:MCP text not found error 沒提示有 math_script_insensitive flag,使用者照樣放棄重試。建議在 anchor lookup 失敗時:若 needle 含 Unicode subscript 字元 → error message 加 hint「try match_options.math_script_insensitive: true」。 Server.swift error message paths
6 P2 Schema description 過度承諾:「xᵢ/xi 等視為等價」沒寫支援邊界,LLM caller 會 generalize 到 xᵦ/xβ 結果 0-match。建議列舉支援範圍或加「最完整 list 見 InsertLocation.swift」link。 Server.swift schemas (4 sites)
7 P3 PerformanceAnchorLookupOptions.contains 對全文做 O(N×M) 掃描,沒 short-circuit、沒 benchmark。1000+ paragraph 文件、多次 lookup 場景未驗證 perf。 InsertLocation.swift
8 P3 search_text / replace_text 沒同等 surface:實際 LLM 流量主要走這兩個 tool,PR 只 cover 4 個 insertion tools。replace_text("H₀", "...") 仍會 0-match。 Server.swift (search_text/replace_text 未動)
9 P3 Typo'd keys silently fall back{"match_options": {"math_script_insensitve": true}}(缺 i)會被 silently 忽略而非 reject。Schema 缺 additionalProperties: false Server.swift:119 (parseAnchorLookupOptions)
10 P3 insert_equation 在 inline mode 也 validate match_options(inline mode 不接受 anchor),error precedence 與其他 args 順序略不一致。Cosmetic。 Server.swift:8964 region
11 P3 testInvalidMatchOptionsTypeIsRejected 只檢查 text 內容、沒驗 result.isError。Pre-existing handler 設計問題,本 PR 沿用。 Issue90MathScriptMatchOptionsTests.swift
12 P3 insert_equation / insert_image_from_path 只有 schema test、無 end-to-end 行為測試。code path 共用 helper 風險低,但缺 confidence。 同檔
13 P3 缺 explicit .bool(false) test(omit vs explicit-false 走不同 code path)。 同檔
14 P3 nthInstance 跨形態計數沒 doc:當 needle H 配 flag 開於含 H₀ + H₁ 的 paragraph,nthInstance: 2 應對應 H from H₁ 還是 H from H₀?schema 沒說明。 Server.swift schemas
15 P3 insert_equation schema description 未提及 inline mode 不適用該 flag(README 有寫但 schema 沒)。 Server.swift:8964 schema

Recommended next actions

🛑 Required before merge(P1 #1

  1. Wait for ooxml-swift#38 merge + new release tag (e.g. 0.22.0)
  2. Repoint Package.swift from branch: "codex/math-script-anchor-options"from: "0.22.0"(或對應 tag)
  3. Re-run swift package resolve + 確認 Package.resolved 同步

Strongly recommended(合併前或 follow-up PR 立即跟進,issue body 自身列出的 case)
4. Finding #2:補上 (combining macron U+0304)支援 — issue #90 body 明確列為 anchor pattern。要嘛在 lib mathScriptVariantMap 加 normalization step(先 NFD decompose 再 strip combining marks),要嘛 docs 明示「combining marks not supported, use base character」。建議走 NFD decomposition - issue body 明示這是 use case。

Open follow-up issues(建議批次開)

每個 reviewer findings 詳檔:/tmp/verify_che_word/pr115_findings_{requirements,logic,devils_advocate,codex}.md

Refs #90

@kiki830621

Copy link
Copy Markdown
Member Author

🛑 Required before merge

Per verify triage(https://github.com/PsychQuant/che-word-mcp/pull/115#issuecomment-4364782360):

1. Cross-repo merge gate (P1)

Package.swift:9 暫指 branch: codex/math-script-anchor-optionsooxml-swift#38 仍 OPEN 未合併。Merge gate:

  1. PsychQuant/ooxml-swift#38 merged
  2. 等 ooxml-swift 發新 release(建議 0.22.0
  3. Package.swiftbranch: 改回 from: "0.22.0"
  4. swift package update 同步 Package.resolved
  5. CI 重跑 Issue90MathScriptMatchOptionsTests 通過

2. X̄ (combining macron) 支援(issue body 明列,本 PR 應補)

Issue #90 body 明確列 X̄ = X + ̄ 為典型 anchor pattern。當前 lib mathScriptVariantMap 沒處理 combining macron U+0304,所以 仍 0-match — issue 自身列的 use case 沒解決。

Fix 方向(lib + che-word-mcp 同步)

packages/ooxml-swift/Sources/OOXMLSwift/Models/InsertLocation.swift 的 normalization step 加 NFD decomposition + strip combining marks:

extension String {
    fileprivate var stripCombiningMarks: String {
        let nfd = self.decomposedStringWithCanonicalMapping
        return String(nfd.unicodeScalars.filter { !$0.properties.isDiacritic })
    }
}

// In contains() / canonicalize:
let canonical = self.stripCombiningMarks.mapToAscii(...)

PR description 寫 "temporarily depends on PsychQuant/ooxml-swift#38 branch",現在這個 fix 同樣可以放在 ooxml-swift#38 PR 內(因為這 PR 還 draft 等 #38),合併時順便。

Test

func testInsertParagraphAfterText_CombiningMacron_FlagOn() async throws {
    // doc 含 "假設 X̄ 為樣本平均"
    // insert_paragraph(after_text: "X̄", match_options: {math_script_insensitive: true})
    // OR after_text: "X" with flag on
    // expect: 兩個方向都 match
}

Open follow-ups(已建立,非合併阻擋;剩下的 unicode coverage 可以留 lib audit follow-up,但 X̄ 是 issue body 自身列的 pattern 必須 in-PR fix):

After merge gate (#1) + X̄ fix (#2), this PR can ship. #90 itself can close once #148 (Unicode coverage audit) lands — current PR scope after X̄ fix covers the headline use case.

kiki830621 added a commit that referenced this pull request May 2, 2026
ooxml-swift PR #38 merged + v0.22.0 released. Swap the temporary branch
dependency back to a tag-pinned semver constraint.

Resolves the PR #115 cross-repo merge gate.

Refs PsychQuant/ooxml-swift#38, PsychQuant/ooxml-swift v0.22.0
@kiki830621
kiki830621 marked this pull request as ready for review May 2, 2026 22:43
@kiki830621

Copy link
Copy Markdown
Member Author

✓ Cross-repo merge gate cleared — PR moves out of draft

PsychQuant/ooxml-swift#38 merged + v0.22.0 released. Package.swift now points to from: "0.22.0" (tag-pinned semver, no more branch dep).

What v0.22.0 includes vs the original branch

This means 2 of the 3 required-before-merge items are now done:

Full test status

  • 848 ooxml-swift tests pass (1 skipped)
  • 5 Issue90MathScriptMatchOptionsTests pass against v0.22.0

Open follow-ups (non-blocking)

Tracked at issues #148-154 (Unicode coverage audit / negative tests / discoverability / search_text expose / strict mode / perf / test gaps).

PR is ready for review.

…tools

Closes #90 — agents can now use Unicode subscript /
superscript / combining-mark variants of anchor text and have them match
against the OOXML AST's flatten output (and vice-versa).

What changed:
- AnchorLookupOptions.parseAnchorLookupOptions(args:tool:) helper at top of
  Server.swift parses the new match_options.math_script_insensitive flag
  with strict-bool validation (rejects strings, ints, null).
- 4 insertion tools wired with the new match_options arg:
    - insert_paragraph
    - insert_image_from_path
    - insert_equation
    - insert_caption
  Each schema exposes match_options as optional object; default is .exact
  (omitted match_options or omitted math_script_insensitive both keep the
  pre-fix exact-match behavior, no caller break).
- Lib delegate: ooxml-swift v0.22.x AnchorLookupOptions handles the actual
  bidirectional matching (NFD strip + Unicode subscript/superscript map +
  Greek subscripts U+1D66..U+1D6A + combining marks U+0304 etc).

Tests:
- Issue90MathScriptMatchOptionsTests with 5 cases:
    - testInsertParagraphMatchesH0SubscriptInForwardDirection (H₀ → H0)
    - testInsertCaptionMatchesH0SubscriptInReverseDirection (H0 → H₀)
    - testOmittedMatchOptionsKeepsExactMatching (default preserved)
    - testInvalidMatchOptionsTypeIsRejected (string "true" → error)
    - testMatchOptionsExposedOnFourInsertionTools (schema test)

6-AI verify on this PR:
- 5 Claude reviewers (requirements / logic / security / regression / DA)
- Codex gpt-5.5 xhigh
PASS pending only cross-repo dep, X̄ + ooxml v0.22.0 release.

Refs PsychQuant/ooxml-swift#38 PsychQuant/ooxml-swift v0.22.0
@kiki830621
kiki830621 force-pushed the codex/math-script-match-options branch from e056828 to e2006b7 Compare May 3, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant