opencat / qa
Per-segment quality checks for the OpenCAT Framework
Requires
- php: ^8.2
- ext-intl: *
- ext-mbstring: *
- opencat/core: ^0.1
Requires (Dev)
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2026-05-09 00:58:01 UTC
README
Per-segment quality checks for the OpenCAT Framework.
QualityRunner runs registered checks against a BilingualDocument and returns QualityIssue objects. Checks are small, independent classes — register only the ones you need.
Installation
composer require opencat/qa
Requires ext-intl and ext-mbstring.
Usage
use CatFramework\Qa\QualityRunner; use CatFramework\Qa\Check\TagConsistencyCheck; use CatFramework\Qa\Check\NumberConsistencyCheck; use CatFramework\Qa\Check\EmptyTranslationCheck; use CatFramework\Qa\Check\WhitespaceCheck; use CatFramework\Qa\Check\DoubleSpaceCheck; $runner = new QualityRunner(); $runner->register(new TagConsistencyCheck()); $runner->register(new NumberConsistencyCheck()); $runner->register(new EmptyTranslationCheck()); $runner->register(new WhitespaceCheck()); $runner->register(new DoubleSpaceCheck()); // Run against a full document $issues = $runner->run($doc); foreach ($issues as $issue) { echo "[{$issue->severity->name}] {$issue->checkId}: {$issue->message}" . PHP_EOL; echo " Segment: {$issue->segmentId}" . PHP_EOL; }
Built-in per-segment checks
These implement QualityCheckInterface and run on every SegmentPair:
| Class | Check ID | Severity | What it flags |
|---|---|---|---|
EmptyTranslationCheck |
empty_translation |
ERROR | Target segment is empty or whitespace-only |
TagConsistencyCheck |
tag_consistency |
ERROR | Target has different InlineCode count or types than source |
NumberConsistencyCheck |
number_consistency |
WARNING | Numbers present in source are absent from target |
WhitespaceCheck |
whitespace |
INFO | Leading or trailing whitespace mismatch between source and target |
DoubleSpaceCheck |
double_space |
INFO | Target contains two or more consecutive spaces |
TerminologyConsistencyCheck |
terminology_consistency |
WARNING | A forbidden term is used, or a known source term has no match in the target |
TerminologyConsistencyCheck requires a TerminologyProviderInterface instance:
use CatFramework\Qa\Check\TerminologyConsistencyCheck; use CatFramework\Terminology\Provider\SqliteTerminologyProvider; $provider = new SqliteTerminologyProvider('glossary.db'); $runner->register(new TerminologyConsistencyCheck($provider));
Built-in document-level checks
These implement DocumentQualityCheckInterface and scan the full document after per-segment checks:
| Class | Check ID | Severity | What it flags |
|---|---|---|---|
SegmentConsistencyCheck |
segment_consistency |
WARNING | Identical source segments that have divergent translations |
use CatFramework\Qa\Check\SegmentConsistencyCheck; $runner->registerDocumentCheck(new SegmentConsistencyCheck()); $allIssues = array_merge($runner->run($doc), $runner->runOnDocument($doc));
Running on a single segment pair
$issues = $runner->runOnPair($pair, 'en-US', 'fr-FR');
Useful for incremental QA as the translator edits individual segments.
Writing a custom check
use CatFramework\Core\Contract\QualityCheckInterface; use CatFramework\Core\Enum\QualitySeverity; use CatFramework\Core\Model\QualityIssue; use CatFramework\Core\Model\SegmentPair; class NoCapsCheck implements QualityCheckInterface { public function getId(): string { return 'no_all_caps'; } public function getName(): string { return 'No All-Caps Words'; } public function check(SegmentPair $pair, string $sourceLanguage, string $targetLanguage): array { if ($pair->target === null) { return []; } $text = $pair->target->getPlainText(); if (preg_match('/\b[A-Z]{3,}\b/u', $text)) { return [new QualityIssue( checkId: $this->getId(), severity: QualitySeverity::WARNING, message: 'Target contains all-caps word.', segmentId: $pair->source->id, )]; } return []; } } $runner->register(new NoCapsCheck());
Severity levels
QualitySeverity |
Meaning |
|---|---|
INFO |
Style suggestion — informational only |
WARNING |
Probable error — should be reviewed |
ERROR |
Definite error — must be fixed before delivery |
The opencat/workflow WorkflowOptions::$qaFailOnSeverity option throws WorkflowException if any issue reaches the configured severity level.
Related packages
opencat/core—QualityCheckInterface,DocumentQualityCheckInterface,QualityIssue,QualitySeverityopencat/terminology— providesTerminologyProviderInterfaceforTerminologyConsistencyCheckopencat/workflow— runs QA as the fourth step in the pipeline; supportsqaFailOnSeveritythreshold