2 releases
Uses new Rust 2024
| 0.2.1 | May 3, 2026 |
|---|---|
| 0.2.0 | Apr 14, 2026 |
#1012 in Text processing
Used in 4 crates
2MB
31K
SLoC
marque-engine
Pipeline orchestration for Marque — wires the scanner, parser, and rule sets into a configured, ready-to-run engine.
marque-engine is the middle of the pipeline. It owns the Engine (single
document) and BatchEngine (concurrent, async) APIs that the CLI, the WASM
build, and the server all sit on top of.
Role in Marque
marque-config ─┐
marque-core ───┼─→ marque-engine ─→ LintResult / FixResult + audit log
marque-rules ──┘
The engine drives the scanner, parses each candidate, evaluates every
registered rule with a RuleContext, and — for fix mode — promotes
FixProposals to AppliedFix records when their confidence meets the
configured threshold.
Usage
Single-document lint:
use marque_capco::capco_rules;
use marque_config::Config;
use marque_engine::Engine;
let engine = Engine::new(Config::default(), vec![Box::new(capco_rules())]);
let result = engine.lint(b"(S) example text");
println!("errors: {}, warnings: {}", result.error_count(), result.warn_count());
Apply fixes with audit records:
use marque_engine::{Engine, FixMode};
# use marque_capco::capco_rules;
# use marque_config::Config;
# let engine = Engine::new(Config::default(), vec![Box::new(capco_rules())]);
let result = engine.fix_with_threshold(b"(S) example", FixMode::Apply, None)?;
for applied in &result.applied {
// serialize `applied` to the NDJSON audit stream
}
# Ok::<(), marque_engine::InvalidThreshold>(())
Behavior
- Confidence gate. Only
FixProposals whoseconfidenceis at or above the configured threshold are promoted. Proposals below the gate are surfaced as suggestions inLintResult, never written. - Reverse-span application. Fixes are sorted and applied from the end of the document to the start, so earlier spans remain valid as edits land. Overlapping fixes are rejected per the C-1 invariant.
- Page context. The engine builds a
marque_ism::PageContextfrom preceding portion markings and hands anArc<PageContext>to banner/CAB rules throughRuleContext. The accumulator resets at scanner-emittedMarkingType::PageBreakcandidates (form-feed\fand\n\n\n+), before attempting to parse the page-break candidate, so a malformed candidate cannot block the reset. - Audit log. In production code paths,
AppliedFixis constructed exclusively by the engine via the__engine_promoteconstructor. Rule crates must not bypass this. Test code MAY call__engine_promotedirectly to construct synthetic fixtures for audit-emission unit tests, scoped per Constitution V Principle V (#[cfg(test)]only, never commingled with engine output, and test-fixture construction only — not a general-purpose convenience). See the architectural-invariants section of the workspaceCLAUDE.mdand the__engine_promotedoc comment. - Clock injection.
Engine::with_clockaccepts aClockimpl; aFixedClockis provided for deterministic test snapshots and for the CLI--fixed-timestampdebug flag.
Batch processing
With the batch feature, BatchEngine wraps Engine behind Arc and uses
recoco-utils semaphores for row + byte backpressure. CPU-bound work runs
on tokio::task::spawn_blocking. Results stream out in completion order,
not submission order — correlate by the echoed id.
Features
| Feature | Default | Effect |
|---|---|---|
batch |
on | Enables BatchEngine and pulls in tokio, futures, and recoco-utils. Disable for a leaner sync-only build (e.g. WASM). |
A cache feature (LMDB-backed incremental cache, opt-in) is planned for v0.2
but is not yet present in Cargo.toml.
WASM compatibility
The sync Engine path is WASM-safe; build with default-features = false to
drop the async/batch dependencies. marque-wasm consumes the engine this way.
License
Marque License 1.0 (LicenseRef-MarqueLicense-1.0). See LICENSE.md.
Dependencies
~10–15MB
~174K SLoC