rusdox 1.0.0

Generate DOCX and PDF from YAML at Rust speed.
Documentation
# Production and Batch Rendering

RusDox exposes bounded building blocks for a job runner without pretending that
the local HTTP adapter is a hosted service. A production owner supplies the
queue, authentication, tenant isolation, process/container limits, retention,
and observability. RusDox supplies deterministic preflight, bounded concurrency,
cooperative cancellation, and in-memory artifacts.

## Bounded Rust batches

```rust
use std::sync::Arc;
use rusdox::config::RusdoxConfig;
use rusdox::{
    BatchLimits, BatchRenderer, BatchRequest, CancellationToken, NativeRenderer,
    RenderRequest, RenderSource, SpecFormat, RENDERER_API_VERSION,
};

let batch = BatchRenderer::new(
    Arc::new(NativeRenderer::new(RusdoxConfig::default())),
    BatchLimits {
        max_jobs: 100,
        max_concurrency: 4,
        max_source_bytes_per_job: 2 * 1024 * 1024,
        max_total_source_bytes: 32 * 1024 * 1024,
    },
)?;
let cancellation = CancellationToken::new();
let results = batch.render(vec![BatchRequest {
    id: "invoice-42".into(),
    request: RenderRequest {
        renderer_api_version: RENDERER_API_VERSION,
        source: RenderSource::Inline {
            format: SpecFormat::Yaml,
            content: "version: 1\nblocks: []\n".into(),
        },
        emit_pdf: true,
    },
}], &cancellation)?;
assert_eq!(results[0].id, "invoice-42");
# Ok::<(), rusdox::DocxError>(())
```

Results preserve request order. Invalid capacity or aggregate-source limits fail
before worker creation. Per-item parse/layout failures do not erase successful
siblings. Cancelling a token prevents queued jobs and is observed between parse,
composition, DOCX, and PDF stages.

The test suite renders a 16-document real batch, proves a three-worker ceiling
under contention, cancels queued work, and rejects an aggregate source-memory
budget before any renderer is called. It does not claim hard memory isolation:
use a process/container memory limit when tenants are mutually untrusted.

## Service-owned profiles

The local protocol defaults to the stricter hosted profile:

```bash
rusdox serve stdio --limits-profile hosted --output-root target/jobs
rusdox serve http --limits-file examples/config/hosted-limits.toml \
  --port 4175 --output-root target/jobs
```

`--limits-file` accepts one complete TOML or JSON `InputLimits` object, rejects
unknown fields and zero/inconsistent ceilings, and overrides
`--limits-profile`. Profiles belong to the service owner; protocol clients have
no field that can increase them. The HTTP health response publishes effective
limits so operators can confirm what is active.

## Operational boundary

Prefer one isolated worker process per trust domain. Keep the HTTP adapter on
loopback behind an authenticated owner-controlled gateway, provide a private
output root, bound `--max-requests` to recycle long-lived workers, and use
read-only/curated font and template directories. Treat artifacts as sensitive
tenant data and delete them according to the owner's retention policy.

See [Input safety](input-safety.md), the [v1 security review](security-review-v1.md),
and the [integration protocol](integrations.md) for the complete boundary.