uttrflow / uttrflow/uttrflow-swift
Test MeaningPreservationGuard's changed-quantity rejection, capital-only readings and punctuation-only tokens
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
In `Sources/UttrflowAI/MeaningPreservationGuard.swift`:
- line 262: `verdict(original:rewritten:)` rejects a rewrite whose `changedQuantity` differs ("the rewrite wrote X as another amount"). `changedQuantity` is tested on its own, but this rejection inside the full verdict has never run;
- line 151: `reading(among:heard:standing:)` ignores an offered reading that differs from what was heard only in capitals;
- line 166: `isWritten` returns false for an empty reading;
- line 195: `closedUpEdges` treats a digit as closing the word before it ("mp3", "h264");
- lines 423-424: a token that is only punctuation (a lone dash or ellipsis) carries the sentence start forward.
Measured on origin/main `26d7bc1` with `swift test --enable-code-coverage` (5,384 tests, all passing) and `xcrun llvm-cov export` over the test binary. The regions named below have an execution count of 0: no test runs them, so a change that breaks them passes `make verify`.
## Why it matters
This guard is what stops the language model changing the meaning of a dictation. If the verdict-level quantity check goes, a rewrite of "5%" as "5 percent off", or "$20" as "20", is accepted and typed into the user's message. The other branches decide which words count as the model's own choice, which feeds the same accept or reject decision.
## How to reproduce
Run `swift test --enable-code-coverage`, then `xcrun llvm-cov show -instr-profile .build/debug/codecov/default.profdata .build/debug/UttrflowPackageTests.xctest/Contents/MacOS/UttrflowPackageTests Sources/UttrflowAI/MeaningPreservationGuard.swift` and look for the `0` counts on the lines named above.
## Acceptance criteria
- A `verdict` test where only a quantity's symbol or unit changes (the numerals stay the same) expects `.rejected` with the "as another amount" reason.
- A `candidateVerdict` test where the offered reading equals the heard words apart from capitals expects the reading not to be treated as chosen.
- `isWritten("", in: "anything")` is false; `closedUpEdges("mp3 file")` puts a word end between "mp" and "3".
- A `verdict` case whose rewrite has a stand-alone dash or ellipsis between two sentences is judged the same as the same text without it.
- Each new test fails when the branch it covers is broken. Check this by hand before opening the PR: temporarily change the branch (flip the condition or return the other value), see the test fail, then restore it.
## Where to start
- `Tests/UttrflowAITests/MeaningPreservationGuardTests.swift`. See also `GuardNumberWordsTests.swift` for number cases.
Read `CONTRIBUTING.md` first. Iterate with `swift test --filter `, then run `make verify` before pushing. Only tests change; no product code needs to.
**Size:** S to M.
Contributor guide
Research direction
Read CONTRIBUTING.md first, then open Tests/UttrflowAITests/MeaningPreservationGuardTests.swift and compare number cases in GuardNumberWordsTests.swift. Run the relevant filtered Swift tests while covering the named branches in MeaningPreservationGuard.swift, then run make verify. Done means the acceptance cases pass and each test fails when its covered branch is temporarily broken.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100