Abhishek-Sonje/dot

Python

0

12 commits

updated Sep 12, 2026

See the code

README

DOT

A working local grammar-correction engine with a CLI and loopback JSON API. GECToR handles small edits; Phi-4 Mini runs only for detected residual problems. Rewrites are reviewable suggestions by default.

Run on this machine

The environment and model assets are installed. From the project folder:

./.venv/Scripts/python.exe -m dot "She go to school."
./.venv/Scripts/python.exe -m dot --interactive
./.venv/Scripts/python.exe -m dot --input-file sample.txt

Interactive mode keeps GECToR loaded. Enter one sentence per line; Ctrl+C exits. Outputs are JSON. Use --no-rewrite for GECToR only. Ollama must be running with phi4-mini:latest installed for the optional rewrite step. Choose another installed model with --rewrite-model NAME.

{"original":"She go to school.","corrected":"She goes to school.","status":"corrected","suggestion":null,"rewrite_called":false,"reasons":[]}

Results also include residual_error_probability. This is an uncalibrated detector score, not the probability that the sentence is fully correct.

Fresh setup (Windows)

Requires Git and an existing Python with pip. Run:

powershell -ExecutionPolicy Bypass -File scripts/setup.ps1

Setup creates a project-local Python 3.11 environment, installs the locked CPU dependencies, and downloads approximately 1 GB of model assets. It verifies assets against model-assets.lock.json and can be rerun. Weights, environments and caches are excluded from Git. Only setup requires internet access; GECToR inference resolves local paths with Hugging Face offline mode enabled.

Ollama is installed separately. On this machine, Phi-4 Mini was already installed. Sentence data goes only to 127.0.0.1:11434, with environment proxies disabled.

Local API

./.venv/Scripts/python.exe -m dot --serve 8765

In another terminal:

Invoke-RestMethod http://127.0.0.1:8765/health
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8765/correct -ContentType 'application/json' -Body '{"text":"I has two brother."}'

The server binds only to loopback, processes requests serially, rejects foreign browser origins, and does not log text. /health reports that GECToR is loaded; it does not guarantee Ollama availability. There is no graphical interface yet.

How corrections are chosen

  1. Retain the original verbatim; normalize clear missing negative apostrophes (dont becomes don't) outside URLs and code. Split documents conservatively.
  2. Apply narrow auxiliary agreement rules, then up to three GECToR tag-edit passes.
  3. Check edits against the original. A rejected draft, explicit usage clue, or residual score of at least 0.6 triggers fallback; otherwise stop here.
  4. Ask the local rewrite model for a minimal correction of the ORIGINAL, with neighboring original sentences as read-only context. Never feed it a corrupt draft.
  5. Check original-content preservation, edit limits, and the residual score again. Return passing fallback candidates separately as suggestions by default.

JSON results include normalized, candidate acceptance/rejection details, and edits / suggestion_edits with original character offsets. Documents also include segments; segment edit offsets are relative to that segment, while top-level edit offsets address the entire original. Separator whitespace and line endings survive. Candidate acceptance means it passed these guards, not that correctness is proven.

Edit triage now flags regular lexical past-tense changes without a time cue, plural-to-singular changes, and singular-to-plural changes immediately after a determiner or possessive for review. Each candidate includes edit_decisions. When a full candidate is rejected, independent allowlisted spelling and case fixes can still be retained. Articles and related phrase edits are not detached from their context; they still require whole-candidate validation.

A small explicit typo list supplements residual detection, including contriubuting. This is not a dictionary spellchecker: unknown words and names are not automatically flagged. Literal URLs, email addresses and code are skipped.

Names, pronouns, numeric values, common spelled-out numbers, negation, modal verbs, URLs and code spans are protected heuristically. Auxiliary tense substitutions without a past-time cue are rejected. Moving existing phrases is permitted for suggestions under a separate budget.

--apply-rewrite opts into automatically applying rewrites that also pass the stricter automatic edit budget. Larger phrase movements remain suggestions even with this option enabled.

StatusMeaning
unchangedNo accepted edit; not a certification of correctness.
correctedGECToR edits accepted.
reviewResidual issue, rejected edit, unsupported input, or suggestion to review.
rewrittenAn opted-in rewrite passed the automatic guards.
unavailableGECToR inference failed; original retained.

Verification and observed quality

python -m unittest discover -s tests -v
$env:DOT_TEST_MODELS='1'
./.venv/Scripts/python.exe -m unittest discover -s tests -v
./.venv/Scripts/python.exe scripts/evaluate.py

All 62 tests passed with the actual GECToR model enabled, including the reported negation regression, a longer clause, and paragraph line-ending preservation. Without the opt-in, five real-model tests are skipped.

The prior candidate-routing revision's 48-case development comparison produced (these numbers predate the newer edit-triage policy):

  • 40 exact automatic outputs; 41 including default Phi suggestions.
  • All 16 clean cases preserved.
  • Seven fallback calls out of 48 inputs.
  • The reported dont example now retains negation without invoking fallback.
  • The party example gets a meaning-preserving suggestion, but misses the exact reference's terminal period. Some word-order and heavily broken cases remain unresolved.
  • Optional T5 fallback and T5 verification did not improve the exact-match total.

One other exact-match miss is grammatical: “Please explain to me the problem.” The fixed reference expected a different word order. References were not changed to inflate the result. This tiny set was used during development, so these numbers are not a general accuracy estimate. See evaluation notes and current comparison. The original 28-case results remain historical records, not results for the current implementation.

Optional correction-trained model

Direct T5 experiment (no GECToR or Ollama)

./.venv/Scripts/python.exe -m dot --engine t5-direct "She go to school."
./.venv/Scripts/python.exe -m dot --engine t5-direct --interactive
./.venv/Scripts/python.exe -m dot --engine t5-direct --input-file sample.txt

This is a different execution path, not another fallback layer: the installed Unbabel T5-small runs on every sentence, followed only by existing content/edit guards. No GECToR model, residual detector, likelihood verifier, or Ollama call is used. It also supports --serve PORT. The same specialist setup below installs its assets if needed; there are no additional downloads on this machine.

Read suggestion for a passing candidate. corrected deliberately retains the original because this experiment is manual-review-only; --apply-rewrite is not supported. rewrite_called: false means no fallback was called, not that T5 was skipped. candidates records T5's output and rejection reason. A null residual probability is expected. These lightweight guards cannot prove grammatical completeness or meaning equivalence. Unchanged output is not a correctness verdict.

The default --engine pipeline remains unchanged. The reserved 20 user sentences are not used to tune or compare this experiment.

The default remains GECToR plus selective Phi. To install and try the pinned, approximately 242 MB T5 specialist (already installed on this machine):

./.venv/Scripts/python.exe scripts/download_specialist.py
./.venv/Scripts/python.exe -m dot --fallback t5 "She go to school."
./.venv/Scripts/python.exe -m dot --source-verifier t5 "Its a known fact that there coming to the party tonigh"
./.venv/Scripts/python.exe scripts/compare.py

Fresh setup also accepts -Specialist. Asset hashes are pinned in specialist-assets.lock.json. The experimental verifier compares candidate versus copying-source likelihood; it is not a calibrated semantic check. The T5 fallback is sentence-only; unlike Phi it does not use neighboring context. Comparison needs both the specialist assets and Ollama and writes evaluation/v2-comparison.json.

Limits and next quality milestone

A bounded model-selection experiment now compares the current pipeline with raw local models, including an optional CPU-only, grammar-trained FLAN-T5 Base checkpoint. This does not change DOT's default. The user's 20 new examples are reserved separately in evaluation/heldout-user-001.json, excluded from development comparisons.

This version is deliberately conservative. Documents are limited to 16,000 characters and 40 sentence spans. Each sentence is limited to 240 surface tokens and 6,000 characters; GECToR also enforces a 384-subword limit. Oversized sentences are not silently truncated. Sentence splitting is heuristic, not a full linguistic parser. Spacing inside a corrected sentence may change.

Neither the detector nor these guards prove semantic equivalence. They can miss wrong-word errors, unnamed subject/object swaps, and tense changes outside the covered auxiliary cases. They can also reject legitimate edits. Heavily broken or ambiguous inputs need review; silently accepting the model output is not reliable.

Before widening automatic correction, collect representative user sentences with human-reviewed minimal corrections, then evaluate a held-out set for harmful edits, missed errors, clean-text preservation, rewrite rate and latency. The likely next addition is a calibrated residual-error classifier and stronger semantic checking, not a larger model rewriting every sentence.

Implementation references

Abhishek-Sonje/dot

Python

0

12 commits

updated Sep 12, 2026

See the code

README

DOT

A working local grammar-correction engine with a CLI and loopback JSON API. GECToR handles small edits; Phi-4 Mini runs only for detected residual problems. Rewrites are reviewable suggestions by default.

Run on this machine

The environment and model assets are installed. From the project folder:

./.venv/Scripts/python.exe -m dot "She go to school."
./.venv/Scripts/python.exe -m dot --interactive
./.venv/Scripts/python.exe -m dot --input-file sample.txt

Interactive mode keeps GECToR loaded. Enter one sentence per line; Ctrl+C exits. Outputs are JSON. Use --no-rewrite for GECToR only. Ollama must be running with phi4-mini:latest installed for the optional rewrite step. Choose another installed model with --rewrite-model NAME.

{"original":"She go to school.","corrected":"She goes to school.","status":"corrected","suggestion":null,"rewrite_called":false,"reasons":[]}

Results also include residual_error_probability. This is an uncalibrated detector score, not the probability that the sentence is fully correct.

Fresh setup (Windows)

Requires Git and an existing Python with pip. Run:

powershell -ExecutionPolicy Bypass -File scripts/setup.ps1

Setup creates a project-local Python 3.11 environment, installs the locked CPU dependencies, and downloads approximately 1 GB of model assets. It verifies assets against model-assets.lock.json and can be rerun. Weights, environments and caches are excluded from Git. Only setup requires internet access; GECToR inference resolves local paths with Hugging Face offline mode enabled.

Ollama is installed separately. On this machine, Phi-4 Mini was already installed. Sentence data goes only to 127.0.0.1:11434, with environment proxies disabled.

Local API

./.venv/Scripts/python.exe -m dot --serve 8765

In another terminal:

Invoke-RestMethod http://127.0.0.1:8765/health
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8765/correct -ContentType 'application/json' -Body '{"text":"I has two brother."}'

The server binds only to loopback, processes requests serially, rejects foreign browser origins, and does not log text. /health reports that GECToR is loaded; it does not guarantee Ollama availability. There is no graphical interface yet.

How corrections are chosen

  1. Retain the original verbatim; normalize clear missing negative apostrophes (dont becomes don't) outside URLs and code. Split documents conservatively.
  2. Apply narrow auxiliary agreement rules, then up to three GECToR tag-edit passes.
  3. Check edits against the original. A rejected draft, explicit usage clue, or residual score of at least 0.6 triggers fallback; otherwise stop here.
  4. Ask the local rewrite model for a minimal correction of the ORIGINAL, with neighboring original sentences as read-only context. Never feed it a corrupt draft.
  5. Check original-content preservation, edit limits, and the residual score again. Return passing fallback candidates separately as suggestions by default.

JSON results include normalized, candidate acceptance/rejection details, and edits / suggestion_edits with original character offsets. Documents also include segments; segment edit offsets are relative to that segment, while top-level edit offsets address the entire original. Separator whitespace and line endings survive. Candidate acceptance means it passed these guards, not that correctness is proven.

Edit triage now flags regular lexical past-tense changes without a time cue, plural-to-singular changes, and singular-to-plural changes immediately after a determiner or possessive for review. Each candidate includes edit_decisions. When a full candidate is rejected, independent allowlisted spelling and case fixes can still be retained. Articles and related phrase edits are not detached from their context; they still require whole-candidate validation.

A small explicit typo list supplements residual detection, including contriubuting. This is not a dictionary spellchecker: unknown words and names are not automatically flagged. Literal URLs, email addresses and code are skipped.

Names, pronouns, numeric values, common spelled-out numbers, negation, modal verbs, URLs and code spans are protected heuristically. Auxiliary tense substitutions without a past-time cue are rejected. Moving existing phrases is permitted for suggestions under a separate budget.

--apply-rewrite opts into automatically applying rewrites that also pass the stricter automatic edit budget. Larger phrase movements remain suggestions even with this option enabled.

StatusMeaning
unchangedNo accepted edit; not a certification of correctness.
correctedGECToR edits accepted.
reviewResidual issue, rejected edit, unsupported input, or suggestion to review.
rewrittenAn opted-in rewrite passed the automatic guards.
unavailableGECToR inference failed; original retained.

Verification and observed quality

python -m unittest discover -s tests -v
$env:DOT_TEST_MODELS='1'
./.venv/Scripts/python.exe -m unittest discover -s tests -v
./.venv/Scripts/python.exe scripts/evaluate.py

All 62 tests passed with the actual GECToR model enabled, including the reported negation regression, a longer clause, and paragraph line-ending preservation. Without the opt-in, five real-model tests are skipped.

The prior candidate-routing revision's 48-case development comparison produced (these numbers predate the newer edit-triage policy):

  • 40 exact automatic outputs; 41 including default Phi suggestions.
  • All 16 clean cases preserved.
  • Seven fallback calls out of 48 inputs.
  • The reported dont example now retains negation without invoking fallback.
  • The party example gets a meaning-preserving suggestion, but misses the exact reference's terminal period. Some word-order and heavily broken cases remain unresolved.
  • Optional T5 fallback and T5 verification did not improve the exact-match total.

One other exact-match miss is grammatical: “Please explain to me the problem.” The fixed reference expected a different word order. References were not changed to inflate the result. This tiny set was used during development, so these numbers are not a general accuracy estimate. See evaluation notes and current comparison. The original 28-case results remain historical records, not results for the current implementation.

Optional correction-trained model

Direct T5 experiment (no GECToR or Ollama)

./.venv/Scripts/python.exe -m dot --engine t5-direct "She go to school."
./.venv/Scripts/python.exe -m dot --engine t5-direct --interactive
./.venv/Scripts/python.exe -m dot --engine t5-direct --input-file sample.txt

This is a different execution path, not another fallback layer: the installed Unbabel T5-small runs on every sentence, followed only by existing content/edit guards. No GECToR model, residual detector, likelihood verifier, or Ollama call is used. It also supports --serve PORT. The same specialist setup below installs its assets if needed; there are no additional downloads on this machine.

Read suggestion for a passing candidate. corrected deliberately retains the original because this experiment is manual-review-only; --apply-rewrite is not supported. rewrite_called: false means no fallback was called, not that T5 was skipped. candidates records T5's output and rejection reason. A null residual probability is expected. These lightweight guards cannot prove grammatical completeness or meaning equivalence. Unchanged output is not a correctness verdict.

The default --engine pipeline remains unchanged. The reserved 20 user sentences are not used to tune or compare this experiment.

The default remains GECToR plus selective Phi. To install and try the pinned, approximately 242 MB T5 specialist (already installed on this machine):

./.venv/Scripts/python.exe scripts/download_specialist.py
./.venv/Scripts/python.exe -m dot --fallback t5 "She go to school."
./.venv/Scripts/python.exe -m dot --source-verifier t5 "Its a known fact that there coming to the party tonigh"
./.venv/Scripts/python.exe scripts/compare.py

Fresh setup also accepts -Specialist. Asset hashes are pinned in specialist-assets.lock.json. The experimental verifier compares candidate versus copying-source likelihood; it is not a calibrated semantic check. The T5 fallback is sentence-only; unlike Phi it does not use neighboring context. Comparison needs both the specialist assets and Ollama and writes evaluation/v2-comparison.json.

Limits and next quality milestone

A bounded model-selection experiment now compares the current pipeline with raw local models, including an optional CPU-only, grammar-trained FLAN-T5 Base checkpoint. This does not change DOT's default. The user's 20 new examples are reserved separately in evaluation/heldout-user-001.json, excluded from development comparisons.

This version is deliberately conservative. Documents are limited to 16,000 characters and 40 sentence spans. Each sentence is limited to 240 surface tokens and 6,000 characters; GECToR also enforces a 384-subword limit. Oversized sentences are not silently truncated. Sentence splitting is heuristic, not a full linguistic parser. Spacing inside a corrected sentence may change.

Neither the detector nor these guards prove semantic equivalence. They can miss wrong-word errors, unnamed subject/object swaps, and tense changes outside the covered auxiliary cases. They can also reject legitimate edits. Heavily broken or ambiguous inputs need review; silently accepting the model output is not reliable.

Before widening automatic correction, collect representative user sentences with human-reviewed minimal corrections, then evaluate a held-out set for harmful edits, missed errors, clean-text preservation, rewrite rate and latency. The likely next addition is a calibrated residual-error classifier and stronger semantic checking, not a larger model rewriting every sentence.

Implementation references