<p align="center">
  <img src=".github/social-preview.png" alt="Translate Native — Meaning in. Native language out." width="100%">
</p>

<div align="center">

<pre>
 ____  _     _   _ _   _
| __ )| |   | | | | \ | |
|  _ \| |   | | | |  \| |
| |_) | |___| |_| | |\  |
|____/|_____|\___/|_| \_|
</pre>

# Translate Native

### Meaning in. Native language out. Release only after proof.

One universal agent skill for translations that sound written—not translated—and preserve every language's native script.

<p>
  <img alt="Tests" src="https://github.com/Maykbiletti/translate-native/actions/workflows/test.yml/badge.svg">
  <img alt="MIT License" src="https://img.shields.io/badge/license-MIT-7C3AED?style=flat-square">
  <img alt="Python 3" src="https://img.shields.io/badge/python-3.10%2B-3776AB?style=flat-square">
  <img alt="Dependencies" src="https://img.shields.io/badge/dependencies-zero-16A34A?style=flat-square">
  <img alt="Languages" src="https://img.shields.io/badge/languages-all-E11D48?style=flat-square">
</p>

**Built by BLUN · Skill + MCP + enforced release gate.**

</div>

---

> **Stop translating strings. Start rewriting meaning in the target language.**

Agents can speak beautifully with users in their own language and still produce stiff, literal copy as soon as the task is called “translation” or arrives inside an i18n file. Translate Native prevents that mode switch.

It reconstructs the meaning, discards the source sentence structure, and writes the message again with native syntax, rhythm, idiom, register, script, punctuation, and locale conventions—without changing the facts.

## One skill. Every human language.

The skill has no language allowlist. It applies equally to:

- Swedish, German, Czech, Spanish, Catalan, Basque, and every other Latin-script language;
- Chinese, Japanese, and Korean;
- Arabic, Persian, Urdu, and Hebrew;
- Greek, Cyrillic, Armenian, and Georgian writing systems;
- Indic, Southeast Asian, Indigenous, minority, endangered, and low-resource languages;
- regional standards, scripts, dialects, honorific systems, and specialist registers.

For uncertain and low-resource varieties, the rule is honesty: verify with community and authoritative sources, or request native review. Never fake fluency.

## What changes

| Ordinary translation mode | Translate Native |
| --- | --- |
| Mirrors source word order | Rebuilds native information flow |
| Chooses dictionary equivalents | Chooses native collocations |
| Produces generic “i18n language” | Writes for the real audience and medium |
| Flattens locale and script choices | Resolves locale, script, dialect, and register |
| Drops accents or romanizes native text | Preserves native spelling, diacritics, alphabets, scripts, and punctuation |
| Silently changes emphasis | Preserves claims, modality, negation, and uncertainty |
| Breaks variables during rewriting | Protects keys, placeholders, URLs, markup, and code |

## Two jobs. One mandatory skill.

Agents no longer need to activate a second orthography skill after translating. `translate-native` now owns both jobs in one self-contained release gate:

1. rewrite the meaning as natural original target-language prose;
2. enforce native spelling, diacritics, alphabets, scripts, punctuation, spacing, and Unicode.

The separate `native-diacritics` skill can still protect ordinary writing outside translation tasks. Inside a translation, its activation is optional because the full orthography contract is built directly into `translate-native`.

The root [`AGENTS.md`](AGENTS.md) tells repository-aware agents to load the combined workflow and treat every model-generated translation as an untrusted draft.

## Version 6: mandatory native output for every agent answer

Version 6 extends the gateway beyond translations. Every user-visible natural-language answer now has a release path:

```text
Agent candidate
      ↓ trusted host classifies the task and supplies the expected locale
      ├── response    → release_response
      └── translation → translate-native skill/plugin → release_translation
      ↓
PASS + purpose-bound receipt → deliver
BLOCK                        → revise or stop
```

`release_response` validates the agent's own answer for Unicode integrity, expected script, native spelling and measurable ASCII folding. It rejects `auto` and `all`: the trusted host must supply the exact language or locale rather than letting the agent choose a convenient label. A German answer such as `Haendler pruefen taeglich die Qualitaet im Buero` blocks; the correctly written `Händler prüfen täglich die Qualität im Büro` can pass.

Translations always take the separate, stricter path. The MCP initialization response tells compatible agents to load the installed `translate-native` skill/plugin before drafting, exposes the same workflow as the MCP prompt `translate-native`, and requires `release_translation` for the complete source-target pair. Translation and response receipts are purpose-bound, so a response receipt cannot authorize a translation.

The portable gateway requires a host-owned `task_kind`:

```json
{
  "task_kind": "response",
  "target_text": "Natürlich können wir das zuverlässig prüfen.",
  "language": "de-DE",
  "attestations": {"nativeness": true, "orthography": true}
}
```

For a translation, use `"task_kind": "translation"`, include the complete `source_text`, and supply all seven translation attestations. The gateway blocks ambiguous task kinds, a translation without source, and any attempt to carry a source through the response route.

This covers every human language and writing system, not only German umlauts. The same contract protects Swedish `å/ä/ö`, Czech `č/ř/š/ž`, Spanish accents and punctuation, Vietnamese tone marks, Greek, Cyrillic, Arabic, Hebrew, Indic scripts, Chinese, Japanese, Korean, and languages not named here. Deterministic checks are intentionally conservative and cannot prove perfect native wording; the native-language workflow and human review remain necessary where consequences are material.

### Version 6.155.0: durable general locale-policy invalidation

Version 6.155.0 binds every signed CMS release proof to the exact current
target-locale quality profile, including ordinary website copy. The compact
`{locale, version, sha256}` binding makes the language-policy generation that
governed translation and both review passes independently verifiable at the
publication boundary.

The release service and reference CMS receiver re-resolve that profile before
approval lookup, host commit, active read, health, and idempotent replay. Locale
substitution, profile drift, and resolver failure block fail-closed without
overwriting the last known good content; obsolete content remains safely
tombstonable. Commercial content keeps its separate commercial quality binding
in addition to this universal language-profile proof.

### Version 6.154.0: durable commercial locale-policy invalidation

Version 6.154.0 revalidates the exact commercial quality-profile binding for
the target locale whenever signed release evidence is consumed. A stored CMS
bundle can no longer remain active after its CLDR, morphology, terminology, or
evaluation generation has changed merely because its three-field binding is
still structurally valid.

The check applies before approval lookup, CMS commit, active read, health, and
idempotent replay. Resolver failure and stale or substituted profile bindings
block with the stable release-evidence error; non-commercial evidence remains
strictly null and does not invoke the commercial resolver. The release-evidence
capability contract advertises the exact-current-locale requirement.

### Version 6.153.0: CMS-visible resolution policy

Version 6.153.0 exposes the exact current public commercial-review resolution-
contract SHA-256 in every commercial CMS release proof, including offers whose
first-pass evidence was already `verified`. A CMS can therefore prove which
human-review and independent-model escalation policy governed a signed approval
without decoding opaque job identities or receiving private review data.

Release evidence and its advertised capability contract advance together. The
release service and reference receiver reconstruct the current content-free
contract and reject missing, stale, substituted, or self-rehashed digests before
host commit. Non-commercial evidence requires `null`; only unresolved offers
continue to carry a separate resolution result.

### Version 6.152.0: plan-bound resolution policy

Version 6.152.0 binds the exact public commercial-review resolution-contract
SHA-256 into every commercial plan, per-locale job, and idempotency identity.
Resolution-policy changes therefore create new work identities instead of
silently reinterpreting persisted jobs under newer human-review or independent-
model rules.

The queue revalidates the binding before leasing work, and the worker
reconstructs the complete current content-free contract before loading assets
or contacting the configured provider. The digest continues through the worker
result, quality-evidence request, receipt verification, and signed approval.
Missing, stale, substituted, or self-rehashed bindings fail closed; non-
commercial jobs and results keep the field absent or `null` as their respective
schemas require.

### Version 6.151.0: reviewer-visible resolution contract

Version 6.151.0 supplies unresolved commercial quality reviewers with the
complete public, content-free resolution contract alongside its SHA-256. The
contract declares the exact human and independent-model resolution methods,
provider-separation rule, receipt binding, ordered offer scope, and excluded
private content without exposing source text, target text, prices, brands,
reviewer prose, or identities.

The full contract and digest are bound into the deterministic evidence-request
identity and canonical HTTP payload. The coordinator and transport adapter
independently reconstruct the current contract before provider access, so a
missing, stale, substituted, or merely self-rehashed object fails closed before
authentication or network traffic. Verified commercial results and
non-commercial requests require both fields to be `null`.

### Version 6.150.0: reviewer-visible routing-contract lineage

Version 6.150.0 supplies the exact public offer-routing-contract SHA-256 to
the external quality-evidence provider for every commercial result, including
already verified results that intentionally carry no private offer route. The
digest is part of the deterministic evidence-request identity and the exact
canonical HTTP payload. It therefore matches the field the provider must bind
into its quality receipt without relying on separate capability discovery.

The coordinator and HTTP adapter independently reconstruct the current public
contract before provider access. A missing, stale, substituted, or merely
self-rehashed digest fails closed; non-commercial evidence requests require
`null`. The full routing contract and private Unicode spans remain conditional
on targeted review, and no price, brand, source text, or target text becomes
public evidence.

### Version 6.149.0: signed routing-contract lineage

Version 6.149.0 carries the exact public offer-routing-contract SHA-256 from
each commercial locale job into the worker result, every quality-receipt
binding, the immutable signed approval, and the content-free CMS release
evidence. Each boundary reconstructs or compares the current contract before
accepting the value. Missing, stale, substituted, or merely self-rehashed
bindings therefore fail closed before signing or publication.

Non-commercial results, receipts, approvals, and release evidence require the
field to be `null`. The digest reveals no price, brand, source text, target
text, offer identifier, or private route; the route itself remains confined to
the authorized review path.

### Version 6.148.0: routing-contract-bound job identity

Version 6.148.0 binds the exact public offer-routing-contract SHA-256 into
plan v4, every commercial locale job v4, and their deterministic job,
idempotency, and plan identities. A change to Unicode offset, region coverage,
privacy, or authority semantics therefore creates new work even when the
commercial profile and review-evidence contract are otherwise unchanged.

The worker reconstructs both installed contracts before the first provider
call. Missing, stale, substituted, or merely self-rehashed routing bindings
fail closed; queue health and lease validation inherit the same canonical job
check. Non-commercial jobs omit both commercial digests, and private routes,
prices, brands, source text, and target text remain outside queue metadata.

### Version 6.147.0: exact routing contract for external review

Version 6.147.0 sends the complete, content-free offer-routing contract with
each unresolved commercial quality-evidence request. An independent reviewer
therefore receives the exact Unicode code-point, exclusive-end, length,
registry-order, overlap, privacy, and authority semantics together with the
private route instead of relying on separate capability discovery.

The coordinator and HTTPS adapter independently reconstruct the trusted
contract before authentication or network access. The full contract enters the
deterministic request ID; stale, substituted, or merely self-rehashed objects
fail closed. Verified commercial and non-commercial requests require both the
route and routing contract to be `null`, and no price, brand, offer ID, source
text, target text, or reviewer prose enters the public contract.

### Version 6.146.0: contract-bound private offer routing

Version 6.146.0 publishes a separately versioned, content-free machine
contract for the private offer-routing context. It defines exact Unicode
code-point offsets, exclusive ends, complete text lengths, registry-order
coverage, overlap rules, privacy, and the non-authoritative trust boundary.

Every private route now carries the trusted contract SHA-256. The worker,
evidence request, receipt verifier, release gate, benchmark boundary, and CMS
capability reader independently reconstruct it; a stale, substituted, or merely
self-rehashed contract blocks before provider access or approval. Only the
contract is public. Actual spans, offer identifiers, texts, prices, brands, and
reviewer prose remain private and are absent from CMS release evidence.

### Version 6.145.0: actionable private offer review routing

Version 6.145.0 turns each opaque review-required offer index into an
actionable provider route without weakening the public CMS boundary. The
worker derives a private context containing only ordered numeric indexes,
exact source and target lengths, and validated Unicode code-point regions.

The context is required only for unresolved commercial summaries. It is bound
into the durable evidence request identity and every quality, independent-model,
or qualified-human receipt verification, but is excluded from signed public
release evidence. Missing, reordered, overlapping, empty, out-of-range, or
extra-field routes block before provider access or approval; configured offer
IDs, extracted text, prices, brands, and reviewer prose are never copied into
the routing context.

### Version 6.144.0: targeted per-offer commercial review

Version 6.144.0 retains the exact unresolved offer scope after source-aware
commercial review. The content-free summary identifies affected offers only by
their zero-based registry positions for each dimension, and the independent
model or qualified human resolution must echo that complete ordered scope.

Configured offer identifiers, prices, brands, source text, target text, and
reviewer prose remain private. Missing, reordered, duplicated, out-of-range, or
cross-dimension scope fails closed through the provider-neutral HTTP adapters,
signed release evidence, and CMS boundary. Dimension-level uncertainty without
a registered offer remains routable without inventing an identity.

### Version 6.143.0: complete per-offer commercial evidence

Version 6.143.0 requires every commercial review dimension to carry exactly
one verdict for every registered offer, in registry order. A dimension can no
longer pass globally after reviewing only one price, discount, tax statement,
term, or condition while silently omitting another offer.

The validator derives the global dimension verdict from the per-offer matrix,
requires equivalent, changed, and uncertain offer verdicts to have their own
offer-bound evidence, and rejects duplicates, omissions, reordered offers, and
inconsistent aggregate statuses. The separately hashed contract, commercial
profile, evidence binding, and summary generation advance together, so queued
or cached results under the previous shape fail closed without numeric regexes
or source-locale formatting assumptions.

### Version 6.142.0: stale-job quarantine without head-of-line blocking

Version 6.142.0 quarantines a bounded batch of up to 24 consecutive obsolete
queue jobs inside one claim transaction and continues to the first current job
within that batch. A complete stale EU-locale plan therefore cannot consume 24
service ticks or hold valid work behind it; every quarantined job remains
content-free, terminal, and at zero attempts, with no cache, asset, or provider
access.

The batch decision remains fail-closed and atomic. If later validation is
unavailable, raises unexpectedly, or mutates a decoded payload, all quarantine
and lease changes roll back so recoverable work stays pending.

### Version 6.141.0: current job bindings before lease

Version 6.141.0 revalidates a durable queue job against the exact current
planner and worker contract before granting a lease. A canonical but obsolete
commercial job is marked terminal with the content-free
`job_binding_invalid` reason without consuming an attempt, resolving assets,
consulting translation memory, or reaching a provider.

The queue uses its current local worker contract by default, while the runner
injects the exact worker instance it will execute. Expected binding rejection
is terminal; an unavailable, failing, or payload-mutating validator rolls back
the transaction and leaves the job pending for safe operator recovery.

### Version 6.140.0: current job bindings in read-only health

Version 6.140.0 makes the content-free health monitor revalidate every durable
queue job against the exact current planner and worker contract. A commercial
job can no longer remain health-green after its review-evidence contract has
changed merely because the stored JSON and its payload hash still agree.

Stale or substituted bindings block overall health with
`queue.job_binding_invalid` through local validation. The check is read-only,
independent of provider health, keeps source and target text out of diagnostics,
and leaves valid non-commercial and current commercial jobs unchanged.

### Version 6.139.0: evidence-contract-bound commercial job identity

Version 6.139.0 binds the exact public commercial review-evidence-contract
SHA-256 into plan v3, every commercial job v3, its deterministic job and
idempotency key, and the overall plan ID. A change to offer-registry, Unicode
span, dimension, or verdict semantics now creates new work identity even when
the parent commercial profile identifier remains stable.

Before any provider access, the worker joins the job-bound digest to the
separately verified full contract supplied to source-fidelity review. Missing,
stale, or replaced bindings fail closed; non-commercial jobs remain free of
commercial metadata and no provider is hardwired.

### Version 6.138.0: exact provider-side commercial evidence contract

Version 6.138.0 gives the source-aware commercial fidelity provider the exact,
content-free, SHA-256-bound review-evidence contract rather than only an
illustrative response object. The contract covers the offer registry, Unicode
span semantics, ten commercial checks, limits, verdict invariants, and
fail-closed trust boundary. It is part of the deterministic provider-request
hash and remains absent from transcreation and source-blind native review.

Before any provider call, the worker verifies the contract against the
installed public commercial profile and rejects even a consistently rehashed
substitute. This improves interoperability without hardwiring a provider,
publishing project prices or brands, or treating structural validation as
evidence of semantic truth.

### Version 6.137.0: contract-bound commercial review lineage

Version 6.137.0 binds the exact published commercial review-evidence-contract
SHA-256 into the private evidence hash and content-free review summary. That
closed summary now carries the same digest through worker results, durable
quality-evidence requests and IDs, receipt verification, signed approvals,
translation-memory lookups, and CMS release evidence.

A prior report or summary cannot remain valid after the evidence structure,
offer rules, Unicode span semantics, or verdict invariants change. Missing,
stale, or substituted contract digests block fail-closed before network access,
signing, cache reuse, or CMS publication; no private report content is exposed.

### Version 6.136.0: public commercial evidence contract

Version 6.136.0 publishes the complete commercial evidence shape as a
separately versioned and SHA-256-bound machine contract. CMS backends,
source-fidelity providers, and the portable checker now discover the same
closed fields, limits, Unicode span semantics, offer-region rules, verdict
invariants, and exact ten-dimension order from one provider-neutral source.

The trusted CMS boundary rejects missing, altered, reordered, or merely
self-rehashed evidence contracts before returning capabilities. The contract
explicitly grants no publication authority and makes no semantic truth claim:
uncertain amounts, conditions, or native interpretations still require an
independent model or qualified native-domain reviewer.

### Version 6.135.0: offer-bound commercial evidence

Version 6.135.0 replaces free-form offer labels in commercial review evidence
with a versioned registry of unique offer identifiers and their ordered,
non-overlapping source and target regions. Every price, qualifier, interval,
condition, and assignment span must be contained in the regions declared for
that exact offer, so a reviewer cannot hide a cross-offer swap behind a valid
but unrelated label.

An offer may own multiple discontiguous regions for linked footnotes and
conditions. Every declared offer still needs exactly one matched assignment
item; unknown identifiers, overlapping ownership, missing assignments, and
cross-offer spans block deterministically. The registry validates evidence
ownership, not semantic truth: uncertain boundaries or equivalence continue to
require an independent model or qualified native-domain review.

### Version 6.134.0: durable CMS publisher authorization

Version 6.134.0 retains the original canonical publisher signature beside
every active CMS publication and revalidates it on commit, rendering, health,
and idempotent replay. Rewriting stored payload and release evidence and then
recomputing their unkeyed hashes can no longer create an apparently authorized
bundle after receiver restart.

The SQLite schema migrates from v1 to v2 without inventing missing authority.
An active legacy row without its original signature remains stored but blocked
and unhealthy until the trusted source replaces or tombstones it. Deletion uses
the existing structural-only path, so unsafe legacy content cannot become
undeletable. Superseded and deleted rows scrub the retained signature together
with target prose.

### Version 6.133.0: continuously authorized CMS bundles

Version 6.133.0 closes the durable authorization gap after CMS acceptance.
The reference receiver injects its canonical release-evidence validator into
the SQLite store, which revalidates every active localization against the
current contract and approval expiry on reads, health checks, and idempotent
publication replay. Restarting or upgrading the receiver cannot silently keep
serving a stale authorization.

Expired or contract-stale target content remains blocked without replacing the
last stored bytes. Tombstone registration and deletion use a structural-only
path, so an invalidated bundle can still be removed atomically and cannot trap
unsafe content behind the fail-closed gate.

### Version 6.132.0: contract-bound release evidence

Version 6.132.0 binds the exact SHA-256 of the machine-readable release-evidence
contract into every signed approval and content-free CMS release proof. A delayed
or archived approval therefore cannot be reinterpreted or rewrapped under a
newer field, lineage, commercial-scope, or privacy contract.

The v7 release-evidence validator rejects a missing, malformed, stale, or
substituted contract digest before publication or receiver host commit. The
durable receiver preserves the exact bound proof, and the same fail-closed rule
applies to commercial and non-commercial localizations.

### Version 6.131.0: machine-readable release-evidence contract

Version 6.131.0 publishes a separately hashed, provider-neutral contract for
the content-free release evidence inside the signed CMS capabilities. It fixes
the exact field order, SHA-256 and lineage bindings, commercial nullability,
signed container, and excluded private content so an integration does not need
to reconstruct those rules from prose.

The runtime validates the contract against its private canonical registry on
every capability read. Missing, reordered, altered, or merely self-rehashed
contracts block the complete capability response and publication remains
fail-closed before any CMS commit.

### Version 6.130.0: public evidence lineage

Version 6.130.0 carries the canonical quality-evidence request ID and revision
from the verified signed approval into the closed, content-free public release
evidence. A downstream CMS can now audit and policy-gate the exact evidence
generation without access to provider receipts or private review state.

The release-evidence schema advances to v6. Missing or malformed lineage blocks
before host commit, while any change to the already signed publication bytes
fails authentication. The durable receiver preserves the exact fields and
still exposes no source text, target text, raw receipt, reviewer identity, or
reviewer prose.

### Version 6.129.0: evidence-context-bound approval

Version 6.129.0 carries the canonical quality-evidence request ID and evidence
revision into every purpose-specific receipt-verification binding and into the
signed durable approval. A provider cannot relabel an otherwise valid quality,
qualified-human, or independent-model receipt under a newer evidence envelope.

The receipt binding advances to v5 and the signed approval to v5. Missing,
malformed, stale, or substituted evidence context blocks before verifier or
signer access; changing either dimension also derives a new verifier HTTP
idempotency key. Raw receipts remain outside durable translation memory.

### Version 6.128.0: derived quality-evidence identity

Version 6.128.0 makes the quality-evidence request ID independently
derivable at every local and network boundary. The durable lease store and
provider-neutral HTTPS adapter now recompute the ID from the same exact
versioned field set after validating the complete source and target hashes.

The evidence request advances to v8. A random ID, a stale ID retained after
changing locale, policy, profile, provider, confidence, result or commercial
contract, and an ID derived from an incomplete field set all block before a
database row, authentication callback or network request. The request ID,
canonical request digest and receipt binding remain separate proofs.

### Version 6.127.0: contract-bound commercial evidence

Version 6.127.0 binds every unresolved commercial evidence request and receipt
to the exact advertised review-resolution contract SHA-256. The binding enters
the deterministic request ID, the provider-neutral HTTPS request, each receipt
verification context, and the signed durable approval.

The evidence request advances to v7, the receipt binding to v4, and the signed
approval to v4. A missing, stale, self-selected, or non-commercial contract
digest blocks before authentication, provider transport, approval, or CMS
publication. Verified commercial results and all other content types require a
null binding, so the escalation contract cannot leak into unrelated work.

### Version 6.126.0: independently verifiable commercial resolution

Version 6.126.0 makes targeted commercial-review resolution independently
verifiable at the CMS boundary. Each content-free resolution now binds the
exact commercial profile, the advertised resolution-contract SHA-256, and the
primary provider identity. An independent-model route also carries the second
provider identity, whose provider ID must differ from the primary provider.

The commercial profile advances to v8, the CMS capability generation to v7,
the publication HTTP contract to v3, and release evidence to v5. Missing or
altered profile, contract, primary-provider, or independence bindings block
before CMS persistence. Qualified-human identity, raw receipts, credentials,
reviewer prose, prices, brands, source text, and target text remain excluded.

### Version 6.125.0: machine-readable commercial review resolution

Version 6.125.0 publishes a separate, hashed contract for resolving uncertain
commercial checks. It binds the exact ordered dimensions to the unresolved
summary and distinguishes qualified-human review from an independent model,
including the conditional provider fields and verified receipt hash without
exposing the raw receipt, reviewer identity, prose, prices, brands, or content.

The commercial profile advances to v7, the CMS capability generation to v6,
and release evidence to v4. The release path now uses the same provider-neutral
resolution schema advertised by discovery. Reordered or partial dimensions,
an unexpected human provider, a non-independent model, raw-receipt exposure,
or any rehashed contract drift blocks the entire capability response.

### Version 6.124.0: locale-bound commercial review evidence

Version 6.124.0 binds every commercial fidelity-evidence digest to the exact
target locale and commercial locale-quality profile version and SHA-256, in
addition to the commercial profile and exact source and target texts. Evidence
from another locale or an older rendering, morphology, or evaluation generation
therefore cannot be reused as if it covered the current job.

The worker derives this binding only from the already validated job. The
portable checker requires the same three explicit content-free inputs and
reports them only after successful structural validation. Missing or malformed
bindings block without provider, approval, or publication authority.

### Version 6.123.0: end-to-end commercial acceptance binding

Version 6.123.0 requires every accepted commercial submission to prove that
the downstream website used the same 24-locale rendering-registry generation
that the CMS acknowledged at enqueue. A merely well-formed and self-consistent
website capability binding is insufficient when its commercial registry hash
differs from the durable caller-owned contract.

The equality is enforced before acceptance, revalidated from SQLite after
restart and during health checks, and independently checked by the HTTP edge
and provider-neutral reference client. The versioned capability and OpenAPI
contracts advertise the invariant explicitly. Ambiguous or substituted
generations remain fail-closed without exposing price, brand, source, or target
content.

### Version 6.122.0: durable commercial contract acknowledgement

Version 6.122.0 carries the exact commercial profile and 24-locale registry
acknowledgement through the caller-owned outbox, leases, retries, restarts,
queue responses, status reads, lifecycle responses, OpenAPI contract, and
reference client. The content-free binding is now durable evidence rather than
an ingress-only check.

Every stored row is revalidated against its canonical source payload and the
installed commercial contract before work or status can proceed. Altered or
missing bindings block fail-closed. An exact empty schema-v1 outbox is upgraded
transactionally; any populated legacy outbox remains untouched and blocked
because its historic commercial acknowledgement cannot be reconstructed.

### Version 6.121.0: commercial contract acknowledgement at enqueue

Version 6.121.0 closes the transition from commercial-profile discovery to
durable CMS intake. Every enqueue envelope now carries an exact content-free
commercial contract binding. A commercial change must acknowledge the active
profile and 24-locale rendering-registry hashes; every other content type,
cancellation, and tombstone must carry `null`.

The authenticated HTTP body, capability generation, OpenAPI 3.1 conditional,
and provider-neutral reference client all use the same closed binding.
Missing, stale, altered, or cross-scope acknowledgements block before runtime
enqueue and persistence. The acknowledgement contains no amount, brand,
product, source text, target text, credential, or publication authority.

### Version 6.120.0: public commercial localization contract

Version 6.120.0 carries the existing brand-neutral price and offer profile to
the outer public CMS dispatch edge. The capability generation, separately
scoped body-free route, OpenAPI 3.1 document, runtime, and provider-neutral
reference client expose the exact ten semantic dimensions and all 24
locale-specific Unicode CLDR rendering references. No project price, brand,
product, credential, source text, or target text is part of the response.

The route fetches and revalidates the live downstream website capability
generation before returning the local contract. Its commercial-rendering hash
must equal the bundled canonical registry; a missing, stale, substituted, or
malformed binding blocks before serialization. The result is explicitly
content-free and grants neither linguistic approval nor publication authority.

### Version 6.119.0: verified outer lifecycle read

Version 6.119.0 completes the post-intake read path for non-Python CMS
backends. A dedicated tenant-bound operation carries the full known request
identity through the caller-owned outbox, process-guarded runtime,
authenticated HTTP edge, capability generation, OpenAPI 3.1 profile, and
provider-neutral reference client. It reads the already verified downstream
source lifecycle only after durable website acceptance.

Pending, retrying, leased, and failed outer records cause no downstream read.
The returned lifecycle keeps local dispatch status, website generation,
sidecar generation, source generation, and source processing state separate;
acceptance remains explicitly non-publication. Missing, foreign, substituted,
or internally inconsistent identities and bindings fail closed.

### Version 6.118.0: visible accepted website generation

Version 6.118.0 carries the complete verified website capability binding from
durable intake into the outer CMS dispatch status, authenticated HTTP edge,
capability snapshot, OpenAPI profile, and provider-neutral reference client.
An accepted status now identifies the exact delivery, runtime, commercial
rendering, and terminal receiver generations that accepted the request. An
outer dispatch row that is still pending or has failed exposes no such binding.

The projection is reconstructed only from the already validated canonical
response stored by the outbox. Its inner binding hash and delivery capability
pin are checked again at every status boundary. Missing, altered, partially
substituted, or prematurely populated bindings fail closed. Tests cover all
three operations, pre-acceptance absence, authenticated status serialization,
client-side substitution, and validated restart recovery.

### Version 6.117.0: receiver-bound website delivery generation

Version 6.117.0 binds the website-side durable delivery generation to the
terminal receiver capability SHA-256 already verified by the source runtime.
The trusted host carries that pin through the sidecar adapter, its synthetic
contract digest, the guarded SQLite binding, and the public submission
capability snapshot. A missing, changed, or substituted receiver generation
now blocks restart and queue access before any downstream network call.

The binding table advances to v2 and the adapter contract to v3. An exact,
empty v1 database can migrate transactionally only when its historical v2
adapter digest is reconstructed from the same trusted inputs. A non-empty,
ambiguous, altered, or unbound generation remains fail-closed. Tests cover
restart drift, in-process mutation, exact empty migration, legacy work, and
outer capability tampering.

### Version 6.116.0: receiver-bound public source projections

Version 6.116.0 carries the terminal receiver capability SHA-256 through the
source service's status and health projections, the authenticated HTTP edge,
the provider-neutral reference client, and the outer CMS lifecycle view. A
healthy enabled monitor now exposes the same exact digest at both service and
component level; disabled monitoring remains explicitly `null`.

The source status, health, and capability schemas advance together so old
deployment pins cannot silently accept the expanded contract. Missing,
substituted, malformed, or internally inconsistent receiver bindings block
before a caller can trust the projected processing state. Tests exercise the
real WSGI path and reject altered status, health, and outer lifecycle views.

### Version 6.115.0: durable terminal-monitor capability binding

Version 6.115.0 binds the source CMS's durable terminal-processing monitor to
one exact receiver capability SHA-256. The pin is stored in the monitor schema,
returned in content-free health, checked before status, health, and worker
progress, and required on every accepted receiver status response. A changed
client pin or response generation now blocks before remote state can replace
known state.

An empty v1 monitor can be transactionally adopted into the bound v2 schema.
Existing unbound monitoring work is never guessed or relabelled: startup stays
fail-closed until the operator resolves it under verified deployment evidence.
Tests cover response substitution, runtime pin mutation, restart drift, empty
migration, and non-empty legacy rejection.

### Version 6.114.0: race-free terminal receiver contract

Version 6.114.0 closes the capability discovery-to-operation race across the
terminal CMS callback boundary. Every notification, status, health, readiness,
and OpenAPI request now carries the exact freshly verified receiver capability
SHA-256 in the authenticated
`X-Localization-Capabilities-SHA256` precondition header. Missing and stale
generations return `428` and `412` before durable intake or operational access.

The v3 receiver capability contract and v2 OpenAPI document publish this rule
for every non-discovery operation. Both reference clients reserve and bind the
header, including the one-attempt notifier's deployment-pinned capability
digest. Tests prove stale generations cannot store a notification and that all
control routes remain read-only when their precondition fails.

### Version 6.113.0: verified terminal receiver OpenAPI client

Version 6.113.0 completes the provider-neutral OpenAPI path through the
terminal receiver reference client. `openapi()` performs fresh pinned
capability discovery, fetches the separately authenticated document, and
reconstructs the only acceptable OpenAPI 3.1 profile locally from that exact
generation. A substituted document cannot become trusted by recomputing its
own hash, and generation changes between the two requests fail closed.

The bounded transport now distinguishes the 16-KiB request limit from the
advertised 1-MiB response limit, allowing the complete closed contract without
weakening request validation. Tests cover the real large response, custom
notification paths, self-rehashed substitutions, capability races, oversized
responses, and read-only runtime behavior.

### Version 6.112.0: capability-bound terminal receiver OpenAPI

Version 6.112.0 completes the machine-readable callback contract for the
durable CMS terminal-notification receiver. Its authenticated, separately
scoped OpenAPI 3.1 route publishes all six active operations, including a
custom intake path, closed request and response schemas, required binding
headers, fail-closed error forms, and degraded monitor responses.

The v2 receiver capability generation pins the OpenAPI document schema and
operation. Every returned document and envelope is bound to the complete
capability SHA-256, and the envelope also carries the canonical document hash.
The route reads no inbox content, claims no processing lease, and performs no
model or publication work.

### Version 6.111.0: capability-preconditioned CMS operations

Version 6.111.0 closes the capability discovery-to-operation race at the
public CMS sidecar. Every route except capability discovery now requires the
authenticated `X-Localization-Capabilities-SHA256` header to equal the exact
active complete capability generation. A missing precondition returns the
contract-bound `428`; a stale or substituted generation returns `412` before
enqueue, status lookup, monitor access, OpenAPI generation, or other runtime
work. The reference client reserves and supplies the header automatically and
includes the digest in its host-authentication context.

The v8 capability contract and v7 OpenAPI document publish the required header
per operation and bind both precondition failures to their exact status and
error code. Capability discovery remains the single authenticated bootstrap
route and does not require knowledge of its own response digest.

### Version 6.110.0: exact CMS error reasons

Version 6.110.0 binds every public CMS sidecar failure reason to its exact
route and HTTP status. The ordered error-code maps participate in the
capability SHA-256 and are reproduced as closed per-response enums in OpenAPI.
Bodyless discovery and monitor routes now also advertise their real `411` and
`413` framing outcomes, so generated clients do not mistake an oversized or
invalid `Content-Length` for an undocumented server response.

The provider-neutral reference client validates the complete error envelope
against that pinned map before exposing its status and stable remote code as
content-free exception metadata. Unknown codes, extra fields, mismatched
statuses, malformed JSON, and stale capability generations remain blocked.
Only a verified advertised server failure can influence the caller's retry
decision; no source or target content is copied into the exception message.

### Version 6.109.0: executable CMS state invariants

Version 6.109.0 binds the public CMS sidecar's cross-field state rules into
the live capability generation and its OpenAPI profile. Generated validators
can now reject a leased submission without an expiry, a non-leased submission
with one, or an accepted submission without all remote status, attempt and
digest evidence. Relationships that JSON Schema cannot express portably, such
as attempt ceilings and request-identity equality, remain explicit stable
invariant identifiers rather than disappearing into prose.

Health now proves that `ok` has neither failed work nor expired leases, while a
blocked state must have at least one of them. Readiness is a closed union:
`ready` requires a running worker, healthy outbox and no error; `not_ready`
requires a content-free error code. Every operation publishes its exact
response-invariant list, which participates in the capability SHA-256 and is
copied unchanged into OpenAPI.

### Version 6.108.0: exact CMS failure contracts

Version 6.108.0 makes every public CMS sidecar outcome explicit in both live
capabilities and OpenAPI. Each operation publishes its complete bounded set of
HTTP error statuses alongside its success status; those lists participate in
the capability SHA-256 and are reproduced as concrete OpenAPI responses rather
than an ambiguous `default` branch. A stale client therefore cannot silently
miss a conflict, tenant-safe not-found result, framing rejection, or runtime
outage while still matching the active deployment pin.

Health and readiness now model their real `503` behavior precisely. The body
may be a validated content-free degraded monitor response or a fail-closed
error envelope, expressed as a closed `oneOf`; all other advertised non-success
statuses accept only the error envelope. Runtime tests compare every operation,
status code, extension, and response schema with the live capability generation.

### Version 6.107.0: self-describing CMS capabilities

Version 6.107.0 closes the remaining untyped discovery boundary in the public
CMS OpenAPI profile. `CapabilitiesResponse` now references a recursively
closed schema for the complete active capability generation: all routes,
methods, scopes, principals, request and response schemas, limits, retry
owners, source-event schemas, downstream pin, and fail-closed semantics are
fixed values rather than an open object.

The capability document now also carries the exact OpenAPI document schema
version. That field participates in the capability SHA-256, so an older or
substituted API description cannot retain the same deployment pin. Runtime
fixtures verify every nested property, leaf value, required field, and
`additionalProperties: false` boundary without storing customer content.

### Version 6.106.0: closed CMS source payload schemas

Version 6.106.0 makes the capability-bound OpenAPI document directly usable
for CMS client generation. Its enqueue body now contains a discriminated,
closed union for one content change, cancellation, or tombstone instead of an
opaque payload object. Every operation has its exact runtime schema ID,
required identity fields, positive source generation, and no unknown fields.

The content-change schema includes the complete provider-neutral localization
request: source identity and NFC text, exact BCP-47 locale, content type,
glossary, policy, model and software versions, and an optional unique target
set restricted to all 24 current EU locale profiles. Runtime validation remains
authoritative for UTF-8 byte limits, canonical locale casing, and exclusion of
the source language. The v3 capability hash binds all three payload schema IDs,
so stale generated clients fail closed before enqueue.

### Version 6.105.0: capability-bound OpenAPI discovery

Version 6.105.0 publishes an authenticated, origin-free OpenAPI 3.1 document
for all six public CMS submission sidecar operations. The document is built
from the freshly validated capability generation and fixes every method, path,
scope, principal type, request and response schema, transport limit, retry
owner, and fail-closed publication semantic. It contains no deployment origin,
tenant identity, website content, provider choice, or credential value.

The HTTPS reference client fetches the live capability document before the
OpenAPI route and reconstructs the expected document from its two immutable
deployment pins. A substituted document still blocks when an attacker changes
it and recomputes its own hash. This gives CMS generators a machine-readable
contract without allowing discovery to weaken authentication, idempotency,
tenant isolation, or the rule that intake does not authorize publication.

### Version 6.104.0: contract-pinned public submission sidecar client

Version 6.104.0 gives non-Python CMS and website backends a provider-neutral
HTTPS reference client for all five public-submission sidecar routes. Before
every enqueue, status, health, or readiness operation, it discovers and exactly
validates the live contract against separate immutable pins for the sidecar and
the downstream public website capability generation. A self-rehashed old or
altered contract therefore blocks before a write.

Authentication receives the exact method, origin, path, scope, body hash, and
request identity but cannot replace framing, idempotency, or source-payload
headers. Every request has one bounded transport attempt, redirects are
terminal, and retry scheduling remains with the caller. Responses are closed,
content-free shapes bound to the full tenant identity, all three retry budgets,
and both capability generations; private additions, substituted identities,
or inconsistent health and readiness states fail closed.

### Version 6.103.0: authenticated public submission sidecar

Version 6.103.0 exposes the process-owned CMS submission runtime to non-Python
backends through a strict HTTPS/WSGI boundary. Five separately scoped routes
cover durable enqueue, tenant-bound status, operator health, worker readiness,
and canonical capability discovery. Authentication receives the exact request
body hash before JSON parsing; tenant writes additionally bind the authenticated
site, idempotency key, and canonical source-payload hash.

The enqueue route accepts work only while the supervised worker is ready and
returns HTTP 202 only after the caller-side SQLite commit. Exact replay remains
idempotent, while changed content or any changed retry ceiling conflicts.
Status requires the complete operation, request, event, site, and payload
identity; foreign tenants and mismatched identities are indistinguishable from
missing work. All responses are independently shape-checked and content-free,
and explicitly state that durable website intake grants neither localization
approval nor publication authority.

### Version 6.102.0: supervised public submission runtime

Version 6.102.0 turns the caller-owned public submission outbox into a safe
production composition root. It validates the client capability pin, retry
policy, worker identity, clock, loop timing, and any existing SQLite generation
before operational schema mutation. The resulting process-owned runtime uses an
owner-only identity-guarded database, serializes connection access, and checks
client, file, parent-directory, process, and schema identity around every call.

The optional hosted factory owns one supervised non-daemon worker. Managed
intake is accepted only while that worker is alive; readiness reports worker,
outbox, and exact capability generation without content. Shutdown signals and
joins the worker before closing SQLite, and a timed-out network call leaves the
database open for deliberate recovery. Restarts resume committed requests,
while permission changes, links, inode replacement, schema injection,
capability drift, and post-fork use block before transport.

### Version 6.101.0: durable public submission handoff

Version 6.101.0 gives CMS and website backends a caller-owned durable outbox
for the public submission client. Each complete change, cancellation, or
tombstone is validated and committed to SQLite before network access, together
with its canonical payload hash, idempotency identity, exact public capability
generation, and three independent retry ceilings.

One token-bound lease performs one client call. Explicitly retryable transport
failures use bounded durable backoff; permanent failures and exhausted attempts
remain visibly blocked. A crash after remote acceptance replays the identical
request after lease expiry, while stale claims, changed contracts, altered
payloads, database drift, and foreign response schemas fail closed. Local
`accepted` means only that the website edge durably accepted the request; it
never grants linguistic approval or publication authority.

### Version 6.100.0: contract-pinned public submission client

Version 6.100.0 makes the complete public website submission edge directly
usable through one provider-neutral HTTPS reference client. Before every
change, removal, tenant progress read, or operator probe, the client discovers
and validates the exact live v5 capability snapshot against its deployment
pin; path, scope, schemas, retry ownership, generation hashes, and explicit
non-publication semantics cannot drift independently.

All writes bind their canonical source-payload hash and idempotency identity;
all reads bind the complete known tenant and payload identity. Health and
readiness remain separate site-free operations. Authentication cannot replace
transport-owned headers, responses are revalidated against every nested
generation, and redirects or hidden client retries are forbidden. Invalid
input and stale contracts block before the operational request, while network
retry decisions stay content-free and caller-owned.

### Version 6.99.0: authenticated public pipeline monitoring

Version 6.99.0 exposes separate provider-neutral HTTPS operator reads for the
complete website-to-source health and readiness projections. Both routes are
body-free and content-free, use distinct scopes, and authenticate before any
runtime, queue, or downstream access.

The boundary independently validates the website and sidecar intake state,
the source-service state, every capability generation and both runtime
bindings. Health never substitutes for readiness, neither response identifies
a tenant or includes website content, and neither grants publication
authority. Malformed counters, contradictory component states, altered
bindings, or unavailable downstream evidence block fail-closed.

### Version 6.98.0: authenticated public submission progress

Version 6.98.0 completes the public submit-and-observe path with separate,
provider-neutral HTTPS reads for durable acceptance status and the full source
localization lifecycle. Every lookup is bound to its authenticated site,
operation, request and event identities, and exact source-payload SHA-256
before runtime access.

The boundary independently validates the complete content-free runtime
projection, including retry counters and pinned capability generations. A
foreign tenant is indistinguishable from a missing submission; malformed,
substituted, or cross-bound downstream state fails closed. Acceptance and
source processing remain separate, and neither response grants quality
approval or publication. The v4 capability snapshot advertises both live
read routes, scopes, request/result schemas, and response envelopes.

### Version 6.97.0: authenticated public website submission

Version 6.97.0 exposes the website-owned outer outbox through two provider-
neutral HTTPS write routes for one change or one cancellation/tombstone. Each
request binds its authenticated principal to the exact site, canonical body
hash, source-payload hash, idempotency identity, and separate website-delivery
and source-processing retry ceilings before touching runtime state.

The hosted website worker and the pinned commercial capability generation must
both be ready. HTTP 202 is returned only after the immutable outer-outbox row
has been committed; exact retries reuse that row and changed content or retry
policy conflicts fail closed. The content-free acknowledgement keeps website
acceptance distinct from sidecar/source acceptance, quality approval, and
publication. The v3 public capability snapshot now advertises these live paths,
scopes, schemas, and precise acceptance semantics.

### Version 6.96.0: authenticated website capability discovery

Version 6.96.0 exposes the complete website submission capability as a strict,
read-only WSGI route. The route at
`GET /v1/localization/source-delivery/submission-capabilities` requires HTTPS,
an exact host-authenticated read scope, an empty body, and no query. The
provider-neutral authenticator receives only canonical request metadata and
the empty-body hash before the runtime or downstream sidecar is contacted.

The response admits only the exact V6.96 operation, retry, semantics, and
durable-generation fields and rechecks their canonical SHA-256. Changed
schemas, added private fields, altered publication semantics, stale hashes,
runtime failures, and authentication failures therefore return only stable,
content-free blocking envelopes.

### Version 6.95.0: discoverable end-to-end website capabilities

Version 6.95.0 adds one canonical, content-free capability snapshot at the
outer website submission runtime. It advertises the exact change and removal
schemas, every composed status, lifecycle, health and readiness projection,
the three independently owned retry budgets, and the fail-closed publication
boundary under one deterministic SHA-256. It explicitly states that this edge
neither generates translations nor grants publication authority.

The runtime validates its guarded website database generation before making a
fresh authenticated sidecar capability request. The returned snapshot binds
the exact live sidecar and source-service capability pins to that durable
website generation. Local tampering therefore blocks without network access;
remote contract substitution blocks without returning a weaker capability.

### Version 6.94.0: observable website generation evidence

Version 6.94.0 exposes the outer website outbox's exact, content-free durable
generation as a canonical capability binding. The binding identifies the
website database role, sidecar-adapter contract, source-runtime contract,
commercial rendering registry, and their derived binding hash without
including an endpoint, credential, tenant, source text, or target text.

Every composed submission status, lifecycle, health, pipeline-health,
readiness, and pipeline-readiness projection now carries that independently
validated website binding alongside the existing sidecar and source evidence.
The runtime derives it from the canonical SQLite row on every read. A changed
adapter, malformed or substituted binding, or altered database generation
blocks locally before any operational request reaches the sidecar.

### Version 6.93.0: local-first website restart preflight

Version 6.93.0 validates an existing outer website outbox locally and read-only
before the authenticated sidecar preflight can make a network request. File
ownership, mode and identity, the base outbox schema, the canonical generation
table, its role-specific row, and its derived digest must all match the exact
adapter, source-runtime, and commercial rendering-registry generation.

A changed generation, altered schema, malformed binding, unsafe file, or
non-empty unbound legacy outbox now blocks with a stable content-free reason and
zero transport calls. A missing database is still created only after remote
generation verification, while a provably empty unbound legacy database remains
migratable and is bound only after that same verification succeeds.

### Version 6.92.0: authenticated website generation preflight

Version 6.92.0 closes the remaining durable generation gap at the public
website edge. The owned HMAC submission composition now requires the expected
source-runtime and commercial rendering-registry hashes, verifies both through
the authenticated sidecar source-readiness route, and opens no website database
until that exact content-free binding is proven.

The verified values become part of the sidecar-adapter contract and the outer
website outbox's role-specific SQLite binding. Missing, partial, malformed,
stale, or substituted generations block fail-closed before database creation;
pending website work can resume only with the same adapter, runtime, and price
format generation. Direct low-level adapter use remains compatible and
deliberately unbound unless both generation pins are supplied together.

### Version 6.91.0: durable sidecar generation binding

Version 6.91.0 durably binds the source-delivery sidecar database to the exact
sidecar contract, verified source-runtime capability generation, and commercial
rendering-registry generation. Every restart validates canonical role-specific
metadata and its derived digest before queue or network access. Pending work can
therefore resume only under the generation that accepted it.

An empty unbound legacy outbox may be adopted atomically. A non-empty unbound
outbox, changed capability generation, altered binding record, malformed table,
or attempt to reopen a bound production database without generation pins blocks
fail-closed. Version 6.92 extends the same generation guarantee to the outer
website database.

### Version 6.90.0: authenticated source runtime binding

Version 6.90.0 carries the verified, content-free commercial capability
generation across the authenticated source-service boundary. Production HTTP
startup now requires the existing signed capability preflight before any
database is created. Capabilities, writes, status, health, and readiness all
return the exact durable runtime and commercial rendering-registry binding;
the pinned source client verifies it on every response.

The source-delivery sidecar and owned website runtime preserve that binding as
separate evidence through lifecycle, pipeline health, and pipeline readiness.
Missing, malformed, replaced, or drifting bindings block before acceptance is
reported. This closes the gap between a statically pinned HTTP schema and the
actual commercial policy generation operating the durable queues.

### Version 6.89.0: durable commercial capability binding

Version 6.89.0 preserves the verified commercial capability generation across
CMS worker restarts. The change, removal, and lifecycle databases each retain a
canonical, role-specific binding to the complete capability and commercial
rendering-registry digests. A restart with the same binding resumes pending
work, including recovery from a partially completed same-binding startup.

Another generation, swapped database roles, altered metadata, and non-empty
unbound legacy queues block before service schema changes, queue access, or
provider traffic. Empty legacy stores may be adopted deliberately. This keeps
old price and offer work from silently crossing a policy deployment while
preserving a safe migration path and content-free operational evidence.

### Version 6.88.0: pinned durable CMS startup

Version 6.88.0 carries both commercial capability pins into the durable
source-CMS composition root. An explicit production preflight performs one
signed capability read before any queue database is created, requires the
complete capability and commercial rendering-registry pins, and retains only
their public digests.

Missing pins, transport failure, contract substitution, and either mismatch
leave persistent state untouched and return stable content-free errors. The
runtime exposes the verified binding separately and rechecks it before every
later state transition, so an altered client cannot enqueue or deliver website
content under another commercial contract.

### Version 6.87.0: pinned commercial capability client

Version 6.87.0 completes the public commercial rendering registry at the
source-side reference client. The client now compares the complete v5
capability shape, commercial profile, all 24 locale bindings, and the exact
canonical rendering registry with its installed contract. A substituted
registry remains blocked even if an intermediary recomputes every public
digest.

Deployments may additionally pin the complete capability digest and the
commercial rendering-registry digest in the client constructor. Malformed pins
stop before transport; mismatches stop after one response with distinct,
non-retryable error codes. This makes contract upgrades deliberate without
embedding project prices, brands, credentials, or content in the public
capability path.

### Version 6.86.0: public commercial rendering registry

Version 6.86.0 exposes the complete set of 24 locale-exact commercial
rendering references through the signed CMS capability contract. Every entry
is bound to its exact commercial locale-profile version and digest, and the
whole content-free registry has its own canonical SHA-256 digest. CMS and
website clients can therefore discover and deliberately pin the rules they
need instead of guessing separators, grouping thresholds, currency placement,
or range notation.

The capability contract advances to v5. It reconstructs every advertised
registry entry from the canonical locale profile before returning any data;
missing, reordered, altered, or rehashed entries block the whole response.
The registry contains no project prices, brands, source or target text, or
credentials, and its CLDR guidance still does not claim semantic equivalence.

### Version 6.85.0: locale-exact commercial rendering references

Version 6.85.0 binds an exact Unicode CLDR 48 number-format reference into
every one of the 24 commercial EU-locale profiles. Providers now receive the
resolved CLDR locale, numbering system, grouping threshold, decimal and grouping
symbols, and decimal, percentage, currency, ISO-currency, approximation, limit,
and range patterns in all three ordered phases. Explicit regional data is used
for `de-AT`, `en-IE`, and `pt-PT`; the other configured locales use their CLDR
parent data.

The reference is rendering guidance, never a language-independent semantic
proof. Meaning-preserving number words, written percentages, and equivalent
digit forms remain valid; rounding and currency conversion remain forbidden;
ambiguous values still require an independent model or qualified native-domain
review. The profile generation advances to v5/v2, invalidating stale jobs,
caches, receipts, and publication authority.

### Version 6.84.0: visible commercial escalation resolution

Version 6.84.0 carries the outcome of every targeted commercial escalation to
the CMS receiver. When the primary commercial review remains unresolved, the
signed publication evidence now identifies the exact ordered review dimensions,
whether a qualified human or independent model resolved them, the receipt hash,
and the independent provider binding where applicable.

The release-evidence contract advances to v3. Verified commercial results and
non-commercial content keep a null resolution, while missing, unexpected,
cross-scope, malformed, or method-inconsistent resolution evidence blocks before
the receiver's commit callback. Raw receipts, prices, source or target text,
qualified-human identity, and reviewer prose remain excluded.

### Version 6.83.0: commercial evidence HTTP profile binding

Version 6.83.0 carries the exact locale-specific commercial quality profile
through the provider-neutral quality-evidence and receipt-verification HTTPS
boundaries. Commercial requests now require the nested profile identifier,
version and digest to match their content type, commercial policy and review
summary before authentication or network access.

The evidence request and receipt-binding contracts advance to v6 and v3, so
durable retries and opaque receipts created before this binding cannot be
silently reused. Non-commercial traffic retains the compact base locale
profile and rejects injected commercial scope. A complete coordinator test
drives a Finnish offer through both adapters to signed delivery readiness.

### Version 6.82.0: locale-bound commercial publication evidence

Version 6.82.0 carries each approved commercial locale's exact quality-profile
version and digest through the signed, content-free release evidence to the CMS
receiver. The receiver recomputes the current canonical binding independently
for every locale and blocks stale versions, substituted digests, wrong profile
IDs, missing evidence, and cross-locale reuse before any host commit.

The release-evidence contract is now v2 and remains null-scoped for all
non-commercial content. The durable receiver store also rechecks the compact
binding inside its atomic write transaction, so a malformed commercial bundle
cannot replace the last known good publication even when a callback is invoked
directly.

### Version 6.81.0: locale-bound commercial quality profiles

Version 6.81.0 replaces the one-size-fits-all commercial prompt binding with
24 distinct, canonical EU-locale evaluation profiles. Each profile inherits
the exact locale's native, fidelity, adversarial and source-reference rules,
then adds brand-neutral checks for prices, discounts, qualifiers, tax status,
billing, commitment, renewal, cancellation, conditions and offer assignment.

The complete profile is versioned and hashed into each commercial job. The
worker recomputes it before any provider call and supplies it independently to
transcreation, target-only native review and source-aware fidelity review. Its
version and digest also enter the signed quality-profile result, so profile
changes invalidate job IDs, cached results, review evidence and publication
authority without introducing fixed brands, products or prices.

### Version 6.80.0: end-to-end processing health

Version 6.80.0 adds one authenticated `submission_pipeline_health()` probe
from the website acceptance outbox through the sidecar to every durable source
processing queue. Website intake, sidecar delivery, and source-service health
remain separate content-free projections, including their own counters and
stable error codes.

The probe contacts the source layer only after website and sidecar intake are
healthy. It binds both capability generations and revalidates the complete
source health schema rather than trusting an aggregate flag. Degraded source
registration remains visible, while blocked queues, malformed counters,
transport failure, HTTP/status contradictions, and contract substitution fail
closed without exposing website content, translations, or credentials.

### Version 6.79.0: end-to-end processing readiness

Version 6.79.0 adds one authenticated
`submission_pipeline_readiness()` probe from the website worker through the
sidecar to the source localization service. It reports intake readiness and
source-processing readiness as separate content-free objects and returns
overall `ready` only when all three operated layers are ready.

If the website worker or sidecar is not ready, the probe does not contact the
next layer. Every successful downstream read is bound to the current sidecar
and source-service capability hashes and revalidated against the source
readiness schema. Stopped workers, malformed state, network failures, and
contract substitution therefore remain fail-closed without exposing website
content, credentials, provider responses, or translated text.

### Version 6.78.0: end-to-end localization lifecycle status

Version 6.78.0 adds one authenticated `submission_lifecycle()` read from the
website-owned outbox through the sidecar to the source localization service.
The sidecar exposes the source status only after the exact site, event, and
payload row has reached durable source acceptance; earlier stages remain local
and perform no premature downstream lifecycle request.

The result preserves the acceptance projection and the complete content-free
source-service status as separate nested objects. Event and tenant identity,
payload hash, retry state, required and blocked locales, publication state,
terminal processing, and both capability generations are validated at every
hop. Processing or review can therefore never be collapsed into publication,
and missing, malformed, or stale lifecycle evidence blocks fail-closed.

### Version 6.77.0: end-to-end submission health

Version 6.77.0 adds one content-free `submission_health()` projection across
the website and sidecar acceptance outboxes. It validates local storage before
network access and then uses the owned authenticated, capability-pinned client
to retrieve the downstream snapshot.

Both health objects remain distinct with their counters, due work, expired
leases, failures, contract mismatches, and stable error codes. Overall health
is `ok` only when both outboxes independently report `ok`; malformed state or
contract substitution blocks fail-closed.

### Version 6.76.0: end-to-end submission readiness

Version 6.76.0 adds one content-free `submission_readiness()` projection for
the complete durable website-to-sidecar intake path. It validates the owned
website worker and outbox first; only a locally ready runtime performs the
authenticated sidecar readiness request.

The result keeps website and sidecar worker state, outbox state, stable error
codes, and both capability pins distinct. Overall readiness is positive only
when both durable workers are running and both outboxes are healthy. A stopped
or malformed local runtime causes no remote request, while a blocked sidecar
can never be hidden behind a healthy website worker.

### Version 6.75.0: bound submission progress

Version 6.75.0 adds one content-free `submission_status()` projection across
the website acceptance outbox and the sidecar delivery outbox. Before local
acceptance it reads no remote state; afterwards it authenticates the status
request and binds the returned operation, identities, tenant, payload hash,
capability pins, and independent retry ceilings to the persisted submission.

The result distinguishes `website_acceptance`, `sidecar_delivery`, and
`source_acceptance`. An `accepted` result means only that the source service
durably accepted the event; it never claims that localization, review, or
publication completed. Stale local contracts, malformed remote status, and
changed retry policy fail closed without exposing website content.

### Version 6.74.0: owned authenticated submission runtime

Version 6.74.0 composes the rotating HMAC client, sidecar adapter, private
SQLite outbox, and optional supervised worker into one website-owned runtime.
Invalid transport, retry, worker, or contract configuration fails before the
outbox file is created or any request is sent.

The runtime preserves separate website-acceptance, sidecar-delivery, and
source-processing retry ceilings. It exposes local acceptance and downstream
sidecar status as deliberately different operations, routes live credential
replacement to the exact signer used by the worker, and blocks inherited or
closed instances before storage or network access.

### Version 6.73.0: durable authenticated sidecar submission

Version 6.73.0 connects the contract-pinned, rotatable HMAC sidecar client to
the existing website-owned SQLite outbox through an explicit adapter. A source
event is durable before the first sidecar request, survives a client or process
crash, and is replayed with the same immutable identity until the sidecar has
durably accepted it.

The adapter keeps three retry ceilings distinct: local sidecar-acceptance
attempts, sidecar-to-source-service delivery attempts, and source-service
processing attempts. Its synthetic capability digest binds both remote
contract pins and the inner delivery policy, so a configuration change blocks
old active rows instead of silently changing their semantics.

### Version 6.72.0: source-bound commercial review evidence

Version 6.72.0 binds every content-free commercial review digest to the exact
UTF-8 source and target hashes, the commercial profile generation, and the
complete canonical review evidence. Commercial profile v3 and review-summary
contract v2 invalidate older plans, cache entries, approvals, and capability
pins instead of letting a structurally valid digest move between texts or
policies. The authenticated capability registry publishes the exact versioned
binding recipe without exposing prices, copy, spans, brands, or reviewer prose.

### Version 6.71.0: composed authenticated source-delivery client

Version 6.71.0 provides one provider-neutral client surface for a website
backend to call all six source-delivery sidecar operations. Origin, sidecar
capability pin, and downstream capability pin are supplied once and shared by
the private rotating HMAC signer and contract-pinned HTTPS client, eliminating
duplicate security configuration.

The composed client is bound to its creating process, performs no network call
when construction fails, and routes credential replacement to the exact signer
used by capabilities, changes, removals, status, health, and readiness. Invalid
replacement state keeps the last valid credential, while representations and
errors remain content-free and secret-free.

### Version 6.70.0: uninterrupted source-delivery client rotation

Version 6.70.0 lets a long-lived source-delivery client replace its HMAC
credential without restarting its worker or rebuilding its HTTP adapter. The
provider-neutral rotating signer validates a complete replacement, serializes
the swap with proof creation, retains the last valid signer on failure, and
rejects inherited use from a forked process.

The origin and both capability-contract pins stay immutable throughout the
client lifetime. A safe fleet rollout overlaps old and new generations on the
server, rotates every client, drains proofs and requests already emitted under
the old generation, and only then retires it server-side. The client lock does
not claim to synchronize other processes or requests already in transport.

### Version 6.69.0: uninterrupted source-delivery credential rotation

Version 6.69.0 lets a running authenticated source-delivery sidecar replace
its accepted HMAC credential generations without restarting the outbox worker
or resetting replay protection. Operators may first overlap old and new
generations, move clients, and then retire the old generation.

The runtime materializes and validates the complete replacement before taking
effect, serializes the swap with in-flight authentication, and retains the
last valid verifier on every rejected update. The existing replay ledger stays
authoritative across removal and later re-addition of a generation. Storage,
process, and lifecycle guards are checked before a replacement; errors and
representations expose neither credentials nor secret-manager detail.

### Version 6.68.0: protected authenticated sidecar runtime

Version 6.68.0 turns the source-delivery HMAC reference into one deployable
host composition. It preflights the complete authentication, worker, retry,
contract-pin, and path configuration in memory before opening either durable
database, then owns the hosted delivery runtime and its separate replay ledger
as one lifecycle.

The replay database is created owner-only and bound to its process, inode, safe
parent chain, and serialized connection. Permission drift, links, replacement,
corrupt retained nonces, inherited pre-fork state, closed runtimes, or storage
failure make authentication unavailable before the protected outbox is read or
written. A content-free authentication health snapshot remains separate from
website content and credentials. Shutdown closes the delivery worker and
outbox before the replay ledger; if a worker exceeds its bound, authentication
stays open for an explicit supervisor decision.

### Version 6.67.0: rotatable source-delivery authentication

Version 6.67.0 completes a deployable authentication path for the
source-delivery sidecar without fixing one identity provider. The reference
client signer and server verifier bind the exact origin, method, verified path,
route scope, body hash, tenant identities, idempotency headers, and both active
capability-contract digests into one canonical HMAC-SHA-256 proof.

Credentials carry an explicit generation and allowlist of scopes, so several
versions can overlap during controlled rotation without granting another site.
A caller-owned durable SQLite replay store atomically consumes every random
nonce before protected content is parsed or persisted. Expired, future,
replayed, altered, retired, cross-tenant, or wrongly scoped proofs fail closed;
store and clock outages remain distinguishable, content-free retryable server
failures. No key, credential, website text, or provider response is represented
or stored in the replay ledger.

### Version 6.66.0: contract-pinned source-delivery sidecar client

Version 6.66.0 gives CMS and website backends one provider-neutral HTTPS
reference client for the source-delivery sidecar. Every write and operational
read first verifies the complete live capability contract against a trusted
sidecar pin, then uses only its freshly verified method and path.

The client separately pins the downstream source-service contract, binds
changes and removals to canonical inner-payload hashes and immutable
idempotency identities, and requires complete known bindings for status reads.
Authentication code cannot replace reserved transport headers. Redirects,
hidden retries, tenant substitutions, changed retry ceilings, stale capability
digests, malformed blocked states, and private transport failures remain
content-free and fail closed.

### Version 6.65.0: website-source delivery HTTP sidecar

Version 6.65.0 lets non-Python websites and CMS backends use the protected
source-delivery runtime through one provider-neutral HTTPS/WSGI boundary. Six
separately scoped routes accept changes and removals or expose status, health,
readiness, and a canonically hashed machine-readable contract.

Authentication is bound to the exact method, path, headers, and request-body
SHA-256 before JSON is parsed. Writes additionally require the immutable
request ID, canonical source-payload hash, exact website tenant, both retry
ceilings, and a live managed worker before new work is persisted. Responses are
independently validated and contain only durable identities, hashes, counters,
states, and stable errors; a missing or foreign website item is
indistinguishable. The hosted factory can construct the runtime, worker, and
sidecar as one preflighted unit without creating storage for an invalid
authenticator.

### Version 6.64.0: hosted website-source delivery runtime

Version 6.64.0 turns the durable website outbox into an owned production
runtime. Configuration and lease safety are proven in memory before one
private SQLite file is created. Every later operation rechecks the database
path and inode, rejects links or weakened permissions, serializes threads, and
blocks an inherited pre-fork runtime before it can enter a lock or call the
source client.

The hosted factory starts one supervised non-daemon worker and gates new
managed intake on its live state. Readiness combines worker liveness with the
outbox's fail-closed health without exposing website content. Shutdown signals
the worker before joining it; if a provider call exceeds the bound, the
database remains open until the worker has safely returned.

### Version 6.63.0: durable website-source delivery

Version 6.63.0 gives website and CMS backends a durable handoff to the
contract-pinned source client. The new SQLite outbox persists each immutable
change, cancellation, or tombstone before network access, leases exactly one
attempt to one worker, and safely replays the same idempotency identity after
an ambiguous response or process crash.

Delivery retries and source-service retries have separate bounded ceilings.
Removal work takes priority over ordinary changes; exponential backoff remains
durable across restarts. Exact payload hashes, request identities, source retry
policy, and the trusted capability digest are fixed at enqueue time. Altered
rows, stale leases, exhausted work, invalid acknowledgements, and contract
changes remain content-free and fail closed through explicit status and health
snapshots.

### Version 6.62.0: contract-pinned source-CMS client

Version 6.62.0 completes the public source-ingress path for website and CMS
backends. The new provider-neutral HTTPS client discovers the live contract
before every operation, verifies it against a trusted deployment pin, and uses
only the freshly verified method and path for source changes, cancellations,
tombstones, site-bound status, health, and readiness.

Every write uses one canonical body, one transport attempt, an immutable
idempotency identity, and exact request and payload hashes. All operational
responses now carry the capability digest that authorized their schema; the
client rejects endpoint changes, stale responses, cross-site status, altered
payload hashes, malformed state, redirects, and private transport failures
fail-closed. Stable retryability lets the website host schedule bounded replay
without introducing a hidden retry loop in the adapter.

### Version 6.61.0: durable terminal-processing reconciliation

Version 6.61.0 closes the gap between receiver acceptance and actual CMS-side
processing. When the configured terminal notifier also exposes the pinned
`status(event_id, site_id)` operation, the source service creates an independent
durable processing-observation record after the exact notification
acknowledgement commits. Later ticks poll only that bound event and site.

The observation ledger has its own leases, crash recovery, bounded transport
failures, and polling cadence. It accepts a receiver state only when the
notification ID, event, site, terminal outcome, and payload SHA-256 all match
the delivered record. Pending and leased receiver work stays visible without
being called complete; a remote terminal failure, malformed response, exhausted
status access, expired local lease, or altered ledger blocks health fail-closed.
The authenticated source status and health APIs now expose this content-free
state through their V3 schemas, including stable local and receiver error codes.

### Version 6.60.0: contract-pinned terminal delivery

Version 6.60.0 makes the terminal-receiver client directly usable as the
source service's durable terminal notifier. Before each delivery it validates
the complete immutable notification locally, fetches and verifies the live
receiver contract against the trusted deployment pin, and takes the active
notification path from that verified contract. This supports custom receiver
paths without maintaining a second unpinned delivery configuration.

The write authenticates the exact method, origin, verified path, body SHA-256,
notification, event, and site. Reserved idempotency and binding headers cannot
be supplied by credential code. Only an exact acknowledgement for the same
payload is accepted, and the client exposes stable retryability metadata to the
durable outbox so it alone controls replay. Invalid payloads and contract drift
block before the notification write; redirects, cross-site acknowledgements,
and private transport failures remain fail-closed and content-free.

### Version 6.59.0: response-bound terminal-receiver contract

Version 6.59.0 binds every health, readiness, and site-specific status response
to the exact current terminal-receiver capability SHA-256. The server derives
that binding from its live configured intake path and complete semantic
contract when it creates each response; the operator client requires it to
equal the trusted deployment pin.

This closes the interval between the client's discovery request and its
operational request. A switched endpoint, stale replay, changed custom intake
path, missing binding, or response from another compatible-looking deployment
cannot pass merely because discovery succeeded immediately beforehand. The new
field is part of the canonical advertised response schemas, so old clients and
servers fail closed until upgraded together.

### Version 6.58.0: contract-pinned terminal-receiver operator client

Version 6.58.0 adds a provider-neutral HTTPS client for the terminal receiver's
capability, health, readiness, and site-bound status routes. Deployment code
supplies an expected capability SHA-256 through trusted configuration. Before
every operational read, the client fetches the live contract, verifies its
canonical digest and complete semantics, and requires it to equal that pin.

Each request uses fresh method-, origin-, path-, body-hash-, event-, and
site-bound authentication. The client follows no redirect, makes one bounded
transport attempt per request, accepts only exact UTF-8 JSON schemas and field
sets, and checks cross-field state invariants. A changed route, reused scope,
rehashed semantic downgrade, tenant mismatch, partial health evidence, private
transport exception, or unexpected status blocks with a stable content-free
error before operational data can be trusted. Valid `503` health and readiness
snapshots remain observable as blocked state rather than being mislabeled as a
network failure.

### Version 6.57.0: terminal-receiver operational health API

Version 6.57.0 adds a separately authenticated, body-free health route for
the hosted terminal receiver. It combines runtime ownership, managed-worker
state, verified SQLite inbox integrity, processing counts, due work, expired
leases, and terminal failures in one content-free operational snapshot. HTTP
`200` requires an open runtime, a running or deliberately unmanaged worker,
and an `ok` inbox; every worker or storage failure returns `503` with a stable
error code.

The route authenticates before reading health, never claims work or invokes the
CMS handler, and uses a fifth distinct scope. Aggregate counts contain no site,
event, notification, website text, credential, provider response, or private
exception detail. The discoverable receiver contract now hashes this fifth
operation, its exact schema, fields, path, method, scope, and success status;
path collisions or scope reuse block before SQLite is opened.

### Version 6.56.0: discoverable terminal-receiver contract

Version 6.56.0 adds a separately authenticated, body-free capability route for
the hosted terminal receiver. It publishes the exact active notification,
status, health, readiness, and discovery operations with their methods, paths, scopes,
schemas, required fields, success statuses, transport limits, processing
states, and terminal outcomes. One canonical SHA-256 covers the complete
content-free contract, including a configured custom notification intake path.

The contract is generated from the same constants used by the receiver and
never reads SQLite, claims work, calls the CMS handler, or exposes a site,
notification, website text, credential, or deployment endpoint. A reused
write/read scope, colliding custom intake path, altered notification schema,
non-empty discovery request, malformed transport, or private authentication
failure blocks the complete response instead of advertising a partial or stale
interface.

### Version 6.55.0: terminal-receiver status and readiness API

Version 6.55.0 exposes the hosted terminal receiver's durable processing state
without requiring deployment code to query SQLite. A canonical, authenticated
status request is bound to one event and site and returns only notification
identity, hashes, terminal state, attempts, lease timing, stable error code,
and completion time. A foreign site's event is indistinguishable from a
missing event.

A separate body-free readiness route reports the managed worker and verified
inbox state. Status and readiness use distinct read scopes from notification
delivery, never advance processing, and remain available for diagnosis after
the worker stops or blocks. Plain HTTP, queries, ambiguous framing, invalid
methods, noncanonical bodies, wrong body hashes, scope reuse, storage damage,
and private authenticator failures all produce content-free fail-closed
responses.

### Version 6.54.0: supervised terminal-receiver host

Version 6.54.0 closes the deployment gap between durable terminal receipt and
CMS-side processing. `open_hosted_durable_terminal_notification_receiver`
starts one process-owned, non-daemon background worker that claims and handles
one due notification at a time. State-specific waits are interruptible, so an
idle worker stops promptly without waiting through its configured poll delay.

Once the runtime enters managed mode, HTTP intake succeeds only while the
worker is running and inbox health is `ok`. Startup, stop, callback-loop
failure, terminal processing failure, damaged storage, and inherited pre-fork
instances therefore fail closed before another notification is acknowledged.
`worker_readiness()` exposes only worker state, inbox state, and stable error
codes. `close()` signals and joins the worker before closing SQLite; a bounded
join timeout leaves the database open for an explicit supervisor decision
instead of racing a still-running host callback.

### Version 6.53.0: durable terminal-notification processing

Version 6.53.0 closes the CMS-side callback loop after durable receipt. The
receiver now creates one processing record in the same transaction that stores
and acknowledges a terminal notification. A host worker claims one due record
at a time and receives the exact content-free notification only after the
claim's owner, random token, attempt, deadline, and immutable payload binding
have been committed.

The host returns a bound `processed` acknowledgement. Retryable failures use a
persisted bounded exponential delay; permanent failures and exhausted attempts
remain visible and block health. Expired leases recover after restart, while a
stale worker cannot complete a replacement claim. Unknown callback exceptions
become one stable content-free failure code instead of stored private prose.

Existing V6.51/V6.52 databases migrate transactionally from schema V1 to V2.
Every old receipt is validated before one pending processing record is
backfilled; any altered table or stored binding rolls the whole migration back.
CMS handlers must apply their own side effect idempotently by
`notification_id`, because a crash after that side effect but before the local
completion commit intentionally causes a safe replay.

### Version 6.52.0: protected terminal-receiver runtime

Version 6.52.0 gives the reference terminal receiver a production-oriented
composition root. It validates authentication, origin, route, and HTTPS policy
before opening SQLite, creates a missing database exclusively with mode `0600`,
and rejects symlinks, hard links, special files, shared writable parents,
permission drift, and path replacement. The exact file identity is rechecked
under the runtime lock before every request, status read, and health inspection.

One runtime belongs to one WSGI worker process and owns its connection until an
idempotent close. Inherited pre-fork instances, requests racing shutdown, closed
runtimes, damaged schemas, failed integrity checks, and semantically altered
rows remain fail closed. Restarted workers recover the durable inbox, while a
content-free health result reports only runtime state and received-record count.

### Version 6.51.0: durable terminal-notification receiver

Version 6.51.0 completes the remote terminal callback with a provider-neutral
reference receiver. Its HTTPS-only WSGI boundary validates canonical UTF-8 JSON,
the three reserved identity headers, exact site authorization, and the same
content-free authentication context used by the sending adapter. Authentication
remains host supplied, so bearer tokens, HMAC, mTLS gateways, and other policies
can be integrated without coupling the service to one vendor.

The receiver commits each exact notification to a serialized, process-bound
SQLite inbox before returning the acknowledgement. Replays after a lost response
return the same acknowledgement without changing the original receipt time;
changed data under an existing event, notification, or payload identity conflicts.
Restart recovery, parallel requests, altered storage, malformed framing, wrong-site
credentials, and private verifier failures are covered fail closed without exposing
website content or secret-bearing error detail.

### Version 6.50.0: secure terminal-notification HTTPS adapter

Version 6.50.0 makes the durable terminal outbox deployable across a real CMS
boundary. The provider-neutral callback adapter posts one canonical,
content-free terminal notification to one fixed HTTPS endpoint, never follows
redirects, and never retries inside the transport. A host-supplied
authentication function receives the exact body hash and routing identity, so
deployments may apply their own token, signature, or gateway policy without a
hard-coded provider.

The notification ID and body hash are repeated in reserved idempotency and
binding headers. Only an exact JSON acknowledgement for the same notification,
event, site, and body hash succeeds. Redirects, altered requests, header
injection, duplicate JSON keys, incorrect content types, malformed or oversized
bodies, cross-bound acknowledgements, and private transport exceptions fail
closed. Retryable status and network failures return only stable public codes
to the durable outbox, which remains the sole owner of bounded retries.

### Version 6.49.0: durable terminal notifications

Version 6.49.0 closes the callback gap after lifecycle monitoring reaches a
verified terminal result. Deployments may supply a provider-neutral terminal
notifier; the source service then registers one content-free notification in
the lifecycle database before invoking host code. Event, site, plan, website
version, source sequence, job count, change hash, lifecycle binding, terminal
status, and available lifecycle evidence are bound to one deterministic
notification ID.

The notifier is optional so polling-only integrations remain compatible. When
enabled, each callback attempt uses a durable lease, bounded exponential
backoff, and an explicit attempt ceiling. Only an exact acknowledgement bound
to the notification, event, site, and payload hash completes delivery. Lost
responses replay the same identity; altered evidence, invalid acknowledgements,
expired leases, exhausted attempts, and damaged state block health without
exposing website content or private callback errors.

### Version 6.48.0: supervised source-CMS host lifecycle

Version 6.48.0 closes the operational gap between the durable source-CMS
runtime and a production WSGI host. `open_hosted_cms_source` starts one owned,
non-daemon worker before returning the HTTP application. Its interruptible
sleep allows bounded shutdown without waiting through the idle interval, while
`close` joins the worker before any SQLite connection is closed.

The separately authenticated readiness route reports only worker and service
state. It stays unavailable before startup, after shutdown, on worker failure,
or when durable service health blocks. Once a runtime has entered managed mode,
HTTP change and removal writes fail closed whenever that worker is not running;
no accepted work can silently remain without an active dispatcher. Private
exceptions are reduced to stable codes, and a failed worker cannot be restarted
against potentially inconsistent in-memory state.

### Version 6.47.0: discoverable source-CMS contract

Version 6.47.0 exposes the complete source-CMS HTTP surface through one
authenticated, content-free capabilities route. Integrators receive the exact
active paths, methods, route-specific scopes, principal schemas, request and
response schemas, required top-level fields, success statuses, retry bounds,
and transport limits. A canonical SHA-256 binds the complete advertised
contract for deployment checks and generated clients.

The capability object is derived from the same constants used by WSGI routing
and authentication. It is available only through the separate
`source-capabilities:read` scope, accepts no body or query, touches no runtime
state, and performs no network call. Missing, duplicate, or inconsistent route
metadata blocks the complete response instead of advertising a partial or
stale interface.

### Version 6.46.0: source-CMS lifecycle status

Version 6.46.0 closes the source-CMS request loop with an authenticated,
strictly read-only status route. A CMS can follow one accepted event from its
durable dispatch through lifecycle registration, per-locale processing,
approval, publication, cancellation, or failure without receiving source or
target prose. The response exposes only exact generation identifiers, hashes,
states, bounded counters, locale tags, and stable error codes.

Status credentials are bound to one `site_id` and a separate
`source-status:read` scope. A missing event and an event owned by another site
produce the same content-free response. The runtime revalidates the complete
stored change and lifecycle binding on every read; a corrupt database,
mismatched response identity, malformed principal, or private exception blocks
without repairing state, taking a lease, or performing a network call.

### Version 6.45.0: authenticated source-CMS HTTP ingress

Version 6.45.0 gives the durable source-CMS runtime a strict, optional WSGI
boundary for real CMS deployments. Separate HTTPS routes accept complete
change and removal envelopes or return aggregate health; each route requires
its own authenticated scope. The authenticator receives method, path, bounded
headers, and the exact body hash, but never the website body as a parsed
object. Valid work is persisted before the response and later processed by the
same crash-safe runtime.

The boundary rejects ambiguous framing, transfer encoding, queries, oversized
bodies, duplicate JSON keys, wrong schemas, wrong scopes, and idempotency
collisions. Responses contain only IDs, hashes, counters, states, and stable
error codes. Runtime, database, authentication, and response-shape failures
return fail-closed without exposing source or target text.

### Version 6.44.0: owned source-CMS runtime

Version 6.44.0 makes the coordinated source-CMS service directly deployable as
one owned runtime. Its composition root validates the complete client, worker,
lease, delay, timeout, and database configuration before creating persistent
state; opens three independent owner-only SQLite files; serializes threads;
and rejects use inherited across a process fork before lock or store access.
Restarts and separately constructed workers reuse the existing durable leases,
so accepted changes, removals, and lifecycle polls converge without duplicate
change dispatch. Every public failure remains content-free, and a linked,
hard-linked, aliased, replaced, missing, or permission-weakened database blocks
before the next network operation.

### Version 6.43.0: automatic source-CMS lifecycle service

Version 6.43.0 closes the source-side gap between durable webhook delivery and durable lifecycle observation. One provider-neutral service now prioritizes cancellations and tombstones, dispatches immutable website changes, registers every accepted change for monitoring, and polls verified lifecycle state. A restart after remote acceptance but before local registration reconciles the exact stored acknowledgement without sending the accepted change again. Each tick performs at most one network operation, keeps the existing token-bound outbox leases authoritative, and exposes only content-free status and health data.

### What “mandatory” really means

An MCP server cannot physically stop an agent that is still allowed to print directly to its terminal, Telegram bridge, API response, or file. Non-bypassable enforcement requires the host to capture the complete candidate output, assign `task_kind` and the expected locale outside the agent's control, call the gateway, verify the purpose-bound receipt, and withhold delivery on every failure. If the agent controls the wrapper, signing key, task classification, source, or delivery channel, the installation is advisory.

Version 6.1 therefore installs [`enforced_delivery.py`](integrations/enforced_delivery.py) as `blun-language-deliver`. In mandatory mode the untrusted agent may emit only this envelope:

```json
{
  "target_text": "Natürlich können wir das zuverlässig prüfen.",
  "release_token": "blg6.…"
}
```

The host—not the envelope—supplies `task_kind`, `language`, `source_text`, and content policy. Any attempt by the agent to include or override those fields blocks delivery. Raw text, invalid JSON, a missing token, an edited target, a wrong locale, an expired token, a response token used for translation, an unavailable guard, or a missing key all produce an empty stdout and a nonzero exit.

The wrapper exposes its trusted classification to the child as read-only process context through `BLUN_LANGUAGE_GUARD_MANDATORY`, `BLUN_LANGUAGE_GUARD_TASK_KIND`, `BLUN_LANGUAGE_GUARD_LANGUAGE`, and `BLUN_LANGUAGE_GUARD_CONTENT_TYPE`. This lets the agent call the correct MCP release tool with the expected locale. Changing those variables inside the child cannot change the host policy used for final verification.

Wrap a non-interactive, JSON-only agent command like this:

```bash
blun-language-deliver \
  --task-kind response \
  --language de-AT \
  -- your-agent-command --json-only
```

For translation the trusted host captures the complete source independently and chooses the stricter route:

```bash
blun-language-deliver \
  --task-kind translation \
  --language sv-SE \
  --source-file /trusted/job/source.txt \
  -- your-agent-command --json-only
```

The same module exposes `guarded_send` and `guarded_send_async` for API, Telegram, queue, and web-response adapters. These functions verify before invoking the supplied sender and never invoke it on failure. The host must remove every alternate sender: an agent with direct Telegram/API credentials or an unwrapped stdout path can still bypass any guard.

For a genuine security boundary, run the MCP signer and delivery verifier under a separate OS identity, container, or remote service. The agent must be unable to read the signing key, modify the gateway, change trusted source files, administer the delivery socket, or call the final channel directly. Same-user installation is strong workflow enforcement, not protection against a hostile process with filesystem access.

### Version 6.42.18: Roman-symbol text bypass

Version 6.42.18 protects readable text written with Unicode Roman numeral symbols at Claude's complete `Stop` and `SubagentStop` boundary. Contiguous multi-symbol runs are compatibility-normalized and require an exact signed delivery grant when they cannot be parsed as a non-increasing additive/subtractive Roman number. Literal, lowercase, compound-symbol, and numeric HTML forms such as `ⅭⅠⅤⅠⅭ` now block, while genuine numeric output such as `Ⅻ`, `ⅯⅯⅩⅩⅥ`, additive forms, and isolated symbols remain compatible.

### Version 6.42.17: formatted and compact Morse boundaries

Version 6.42.17 closes the remaining formatting gaps in Claude's complete `Stop` and `SubagentStop` response check. Valid separated Morse runs now remain protected when parentheses, punctuation, or emoji immediately follow the final code, and the exact bounded compact SOS prosign `...---...` is protected in literal, HTML-encoded, and standard typographic form. Short decoration, incomplete compact signals, and longer unbounded dot-dash runs remain compatible.

### Version 6.42.16: Morse output bypass

Version 6.42.16 classifies readable Morse output as natural language at Claude's complete `Stop` and `SubagentStop` boundary. Literal ASCII, standard typographic dots and dashes, numeric HTML references, and emoji-prefixed runs now require an exact signed delivery grant when they contain at least three separated valid Morse letter codes using both signal types. Isolated marks, ellipses, and one- or two-token decorative separators remain compatible to avoid punctuation false positives.

### Version 6.42.15: exact Stop continuation state

Version 6.42.15 requires Anthropic's documented `stop_hook_active` field to be an exact boolean on both `Stop` and `SubagentStop`. Missing, string, numeric, array, object, and null values now terminate processing with `continue: false` before any protected grant state is read. The generic stop reason exposes no response text, and regression tests prove that malformed main and child inputs cannot consume the independently valid one-time grant that a subsequent schema-correct stop still uses.

### Version 6.42.14: symmetric Stop identity isolation

Version 6.42.14 rejects `agent_id` on the dedicated main-thread `Stop` route, matching Anthropic's event schema where the field is added specifically for `SubagentStop`. Together with the existing child-route requirement, neither stop boundary can address the other's grant namespace: a forged main stop carrying a child ID blocks before protected state is read, and the exact child retains its independently consumable one-time grant.

### Version 6.42.13: isolated SubagentStop identity

Version 6.42.13 routes Claude's `SubagentStop` event through a dedicated hook mode and requires its documented `agent_id` explicitly. The trusted route and the reported hook event must match before any protected state is read, so a malformed child stop cannot omit its identity, claim the main-thread route, or consume the parent's one-time grant. Ordinary `Stop` inputs retain the documented absent-`agent_id` fallback to `main` for compatibility.

### Version 6.42.12: exact Claude hook identities

Version 6.42.12 accepts Claude's documented `session_id` and optional `agent_id` only as non-empty strings. Object, array, numeric, empty, and NUL-bearing values now block before protected grant state is read, written, invalidated, or sent to the isolated verifier. This prevents JavaScript coercion from mapping a malformed identity such as `{}` onto the valid string identity `"[object Object]"`; the legitimate session or subagent retains its own one-time grant and remains independently deliverable.

### Version 6.42.11: SignWriting output bypass

Version 6.42.11 classifies two or more Unicode SignWriting symbols as natural language in Claude's complete `Stop` and `SubagentStop` output. Literal, spaced, numerically HTML-encoded, and mixed sign-language writing can no longer bypass the exact-response grant merely because Unicode categorizes its handshape, movement, and location symbols outside the letter category. One isolated SignWriting symbol and pure SignWriting punctuation remain compatible as non-language output.

### Version 6.42.10: Braille output bypass

Version 6.42.10 classifies two or more nonblank Unicode Braille cells as natural language in Claude's complete `Stop` and `SubagentStop` output. Literal, spaced, numerically HTML-encoded, and mixed Braille text can no longer bypass the exact-response grant merely because Unicode categorizes Braille patterns as symbols rather than letters. One isolated cell and the blank Braille pattern remain compatible as non-language output, avoiding false positives for individual markers and spacing.

### Version 6.42.9: regional-indicator output bypass

Version 6.42.9 classifies two or more unpaired Unicode regional indicator symbols as natural language in Claude's complete `Stop` and `SubagentStop` output. Spaced, zero-width-separated, numerically HTML-encoded, and mixed sequences such as `🇭 🇪 🇱 🇱 🇴` can no longer spell readable words outside Unicode's letter category to bypass the exact-response grant. Adjacent pairs remain compatible as ordinary flag emoji, including multiple neighboring or separated flags; one isolated indicator also remains emoji-only. Numeric references are decoded into one visible classification stream without recursively interpreting entity-like replacement text.

### Version 6.42.8: enclosed alphabetic output bypass

Version 6.42.8 classifies Unicode parenthesized, circled, squared, negative-circled, and negative-squared Latin letters as natural language in Claude's complete `Stop` and `SubagentStop` output. Readable text such as `Ⓗⓔⓛⓛⓞ` or `🅗🅔🅛🅛🅞` can no longer bypass the exact-response grant merely because Unicode categorizes the visible letters as symbols. A single enclosed character that Unicode explicitly marks as emoji, such as `Ⓜ️` or `🅰️`, remains compatible as emoji-only output; a sequence of two or more enclosed letter buttons requires verification so short words cannot use the emoji subset as a bypass.

### Version 6.42.7: complete non-language WHATWG references

Version 6.42.7 avoids false positives for every semicolon-terminated named reference in the [WHATWG HTML entity table](https://html.spec.whatwg.org/entities.json) whose complete rendered value contains neither a Unicode letter nor a linguistic combining mark. Mathematical operators, arrows, box-drawing characters, card suits, spacing, and invisible aliases can now pass `Stop` and `SubagentStop` without a translation grant when they contain no prose. Unknown references, language-bearing or linguistic combining-mark references, non-legacy names without a semicolon, and safe references followed by natural language remain fail-closed.

### Version 6.42.6: quarantined temporary Claude cleanup

Version 6.42.6 keeps the creation descriptor open while cleaning up a failed temporary Claude delivery grant or session epoch. The hook first moves the pathname to an unpredictable cleanup quarantine and then proves that the expected creation identity, open descriptor, and quarantined path still identify the same file before unlinking it. A replacement introduced at the former check-to-unlink boundary is preserved under quarantine alongside the original file, and publication blocks fail-closed.

### Version 6.42.5: non-language HTML formatting references

Version 6.42.5 avoids false positives when Claude's complete `Stop` or `SubagentStop` output consists only of standardized named HTML controls and spacing such as `&Tab;`, `&ZeroWidthSpace;`, or `&InvisibleTimes;`. The hook accepts only an exact, case-sensitive, semicolon-terminated set whose rendered values contain neither Unicode letters nor linguistic marks. Semicolonless forms, near misses, unknown names, language-bearing entities, and mixed prose remain fail-closed.

### Version 6.42.4: bounded Claude state reads

Version 6.42.4 bounds the bytes actually read from every Claude delivery-grant and session-epoch descriptor. A file that grows after its initial metadata check can no longer make `readFileSync` consume unbounded data before the final identity check: the hook reads at most the configured limit plus one byte, rejects growth past that limit, and decodes the complete bounded payload as strict UTF-8. Existing BOM handling and exact state validation remain unchanged.

### Version 6.42.3: quarantined Claude state removal

Version 6.42.3 removes the old direct pathname delete after identity validation of a Claude delivery grant or session epoch. The hook now moves the candidate to an unpredictable quarantine name inside the retained protected directory, proves that the open descriptor and quarantined path still identify the inspected file, and only then removes it. A replacement introduced at the former removal boundary is preserved under quarantine and the operation blocks fail-closed instead of deleting the substituted file.

### Version 6.42.2: protected first-use Claude state creation

Version 6.42.2 removes the last recursive path creation from Claude session startup. When the hook state directory does not exist yet, every missing component is now created relative to a retained, no-follow opened, owner-controlled parent-directory handle before any session epoch is registered or published. Linked and broadly writable parents block without receiving a new directory; a parent exchanged during creation receives no state, while safe nested first-use creation remains compatible.

### Version 6.42.1: HTML C1 numeric-reference parity

Version 6.42.1 closes a rendered-output gap in the Claude `Stop` and `SubagentStop` classifier. HTML parsers replace selected numeric C1 control references through the Windows-1252 compatibility table: for example, `&#x8A;` renders as `Š`, even though the raw code point is not a Unicode letter. The hook now classifies the rendered replacement, so decimal, hexadecimal, zero-padded, and semicolonless C1 references that become letters require a release grant. References that render only currency, punctuation, or symbols remain compatible without a natural-language false positive.

### Version 6.42.0: hardened Claude hooks become update-visible

Version 6.42 publishes the accumulated Stop and SubagentStop hardening under a new plugin cache key. Claude Code uses the explicit manifest version to decide whether an installed marketplace plugin needs an update; leaving the version at 6.41.1 would make existing installations report that they were current while retaining the older cached hooks.

`VERSION`, the Claude manifest, the active skill contract, and this README now identify Version 6.42.0 consistently. A repository regression prevents those active version declarations from drifting apart again; every later plugin release must still advance the explicit version with its changed bytes. See Anthropic's official [plugin version-management reference](https://code.claude.com/docs/en/plugins-reference#version-management).

### Version 6.41.1: strict Claude plugin paths

Version 6.41.1 fixes the two remaining path violations reported by Claude's strict plugin validator. The marketplace now declares its repository-root source as `./`, satisfying Claude's requirement that relative marketplace sources start with `./`. The manifest's `skills` entry now names the `./translate-native` directory that contains `SKILL.md`, rather than naming the Markdown file as if it were a skill directory.

The version is bumped because Claude uses the manifest version as the plugin cache and update key; publishing corrected bytes under Version 6.41.0 would leave existing installations unchanged. A repository regression now resolves every declared skill path to a directory containing `SKILL.md` and rejects marketplace sources that do not use Claude's strict relative-path form. Hooks, MCP configuration, delivery policy, and live processes are unchanged. See Anthropic's official [plugin path rules](https://code.claude.com/docs/en/plugins-reference#path-behavior-rules) and [marketplace source rules](https://code.claude.com/docs/en/plugin-marketplaces#relative-paths).

### Version 6.41.0: Claude blocks direct Telegram delivery

Version 6.41 enforces the existing host-owned delivery contract at Claude's tool boundary. A Claude agent can no longer call a Telegram `reply`, `send`, `send_message`, or `sendMessage` MCP tool before its actual final response reaches `Stop`. The `PreToolUse` hook denies only those delivery operations, never copies their candidate text into the denial, and remains closed even when the language service is unavailable. Read-only Telegram operations remain unaffected.

The agent returns its verified final response normally. After `Stop` consumes the fresh grant bound to the exact response, the host-owned bridge remains responsible for delivery. This prevents a direct Telegram tool call from escaping before the lifecycle gate while preserving the non-bypassable host boundary. The implementation follows Anthropic's official [hook reference](https://code.claude.com/docs/en/hooks), where `PreToolUse` can deny a tool call before execution. Regression tests cover the observed `plugin-telegram_telegram.reply` path, candidate confidentiality, and a read-only Telegram control.

### Version 6.40.0: Claude binds release calls to the host language

Version 6.40 closes the remaining Claude-side path behind delayed `language mismatch` failures. When the trusted host supplies `BLUN_LANGUAGE_GUARD_LANGUAGE` or `BLUN_LANGUAGE_GUARD_TASK_KIND`, the plugin repeats that policy at session and prompt boundaries, rewrites the release tool's `language` argument to the exact host tag in `PreToolUse`, and rejects a wrong release purpose. `PostToolUse` independently rechecks both fields before exchanging the receipt for a delivery grant, so an older client, hook race, or direct invocation cannot bypass the binding.

No locale equivalence is introduced: `de`, `de-DE`, and `de-AT` remain distinct signed values. Installations without either host variable retain the existing behavior, while an explicitly present but malformed policy fails closed. The implementation follows Anthropic's official [hook reference](https://code.claude.com/docs/en/hooks): `PreToolUse` may return `updatedInput`, and `UserPromptSubmit` may inject `additionalContext`. Regression tests cover automatic `de-DE` correction, wrong-purpose denial, invalid-policy denial, prompt reinforcement, exact post-tool enforcement, and the no-policy compatibility path.

### Version 6.39.0: authoritative reply language wins over Telegram UI language

Version 6.39 fixes a real delivery failure in which Telegram's `senderLanguageCode` could override the host's configured response locale. That Telegram field describes the sender's client/interface language and is not reliable evidence for the language of the current message. A German release such as `de-DE` could therefore be checked against `en` or another short UI tag and fail with `language mismatch` even though the text was correct.

The BLUN adapter now resolves the language in a strict trust order: explicit per-task guard language, dedicated guard or response configuration, general host language, explicit Telegram conversation language, and only then the legacy sender UI language as a compatibility fallback. The chosen tag is still preserved exactly—`de`, `de-DE`, and `de-AT` are not treated as interchangeable—and the mandatory agent instruction now names the exact release-tool argument. Rejections also identify failed receipt fields without exposing protected text. Regression tests cover configured German with an English Telegram UI, explicit Swedish routing, Catalan conversation metadata, and diagnostic failure output.

### Version 6.38.0: update verifies the checkout after repository tests

Version 6.38 closes the post-test race in forward updates. Post-update tests run without creating Python bytecode, and the updater then requires the exact completely clean tested candidate before any persistent runtime, Claude integration, health monitor, or update state can change.

If uncommitted work appears during the tests, the updater restores the previous revision only through `reset --keep` and preserves the new bytes. If another process creates a commit, it leaves that independent history untouched and does not execute it through an automatic restart. The same rule protects the failing-test path, so a failed candidate can never reset a concurrent commit. Regression tests cover passing and failing tests against both uncommitted and committed races.

### Version 6.37.0: rollback verifies the checkout after runtime probes

Version 6.37 closes the final rollback window between repository tests and updater-state publication. After installed runtimes restart and the optional Claude cache is checked, the repository must still be the exact completely clean tested target before the scheduler is removed or rollback success is recorded.

If uncommitted work appears during runtime verification, rollback safely restores both the forward revision and its runtimes without discarding the new bytes. If another process creates a commit, it leaves that independent history untouched and does not execute it through an automatic restart. Both paths preserve the updater schedule and prior state. Regression tests prove exact `HEAD`, byte preservation, bounded restart behavior, and the absence of scheduler mutation.

### Version 6.36.0: rollback verifies the checkout after repository tests

Version 6.36 closes the remaining test-time race in emergency rollback. The tested ancestor must still be the exact completely clean checkout after its post-rollback test suite finishes and before any installed runtime is restarted or the automatic-update scheduler is changed.

If the tests or another process leave uncommitted work, rollback restores the forward revision only through `reset --keep` and preserves those bytes. If another process creates a commit, the guard leaves that independent history untouched, blocks runtime activation, and requires inspection. Regression tests prove both outcomes and verify that blocked transitions perform no runtime restart or scheduler removal.

### Version 6.35.0: rollback rechecks both sides of the cutover

Version 6.35 applies the updater's complete clean-checkout contract to emergency rollback. Rollback now starts only from a valid exact `HEAD` with every tracked, staged, and untracked path clean, and rechecks that identical revision after candidate tests and Claude cache preflight immediately before changing the repository.

Immediately after `git reset --keep` selects the tested ancestor, rollback requires that exact target and a completely clean checkout before post-tests or runtime activation begin. If uncommitted work appears during cutover, it safely restores the forward revision with `reset --keep` and preserves the new bytes. If another process creates a commit, rollback never rewrites it and blocks runtime activation for manual inspection. Regression tests exercise both dirty and committed races on both sides of the cutover and prove that scheduler removal and runtime restarts never run after a blocked transition.

### Version 6.34.0: update cutover rechecks both sides of the fast-forward

Version 6.34 closes the remaining network and cutover windows in the clean-checkout contract. After the tested revision is fetched, the updater rechecks the exact pre-update `HEAD` and every tracked, staged, and untracked path before running the fast-forward. Work created while the network request is in progress therefore blocks before the repository moves.

Immediately after a successful fast-forward, the updater requires the exact tested revision and a clean checkout before post-update tests or persistent-runtime activation can begin. If uncommitted work appears during the cutover, the updater attempts `git reset --keep`: it returns to the previous revision only when Git can preserve those bytes, otherwise it leaves the state for manual inspection. If another process creates a commit, the updater never resets that independent history. Fetch-time dirty work, fetch-time commits, cutover-time dirty work, and cutover-time commits are separate regression cases.

### Version 6.33.0: automatic updates never mix with local work

Version 6.33 makes a completely clean active checkout a precondition for automatic and manual repository updates. Tracked edits, staged changes and untracked files now block before the temporary candidate is cloned or any repository-owned candidate test can execute. The updater never stashes, resets, deletes or overwrites local work.

The same clean-state and exact-`HEAD` check runs again after candidate tests and Claude plugin preflight, immediately before fetch and fast-forward. If another process edits the checkout or advances its commit during that window, activation stops while both the tested candidate and the local work remain untouched. Rollback already required a clean checkout; forward update now enforces the same fail-closed contract.

### Version 6.32.0: maintenance locks identify the process generation

Version 6.32 prevents a crashed updater's old lock from becoming immortal when the operating system later reuses the same numeric PID for an unrelated process. New locks bind their PID to an immutable process-start identity: Linux combines the kernel boot ID with the process start tick, Windows uses the process creation time through a read-only Win32 handle, and other POSIX systems hash the start timestamp reported by `ps`.

An old lock is recovered only when the PID is dead or the stored and observed process generations definitely differ. If the platform cannot prove the current generation, the lock remains fail-safe and is not removed. Locks written by Version 6.31 remain compatible: a live legacy PID without a generation field is preserved. Exact file-identity checks still protect both stale recovery and normal release from concurrent replacement.

### Version 6.31.0: live maintenance locks cannot expire underneath their owner

Version 6.31 closes a race between long update, rollback and health-monitor operations. The shared lock no longer becomes removable merely because its timestamp is older than 30 minutes. A validated lock whose process is still alive remains authoritative for its complete lifetime, so a slow test suite or plugin preflight cannot be overtaken by a repair process.

Recovery still works after a crash: only an old lock with a confirmed dead owner, or an old malformed lock with no trustworthy owner, may be replaced. Before either stale recovery or normal release deletes anything, the installer rechecks that the path still names the exact file instance it inspected. A concurrently replaced lock is therefore preserved. Lock reads are bounded, regular-file-only and no-follow where the platform supports it; process liveness is checked without sending a signal that changes process state.

### Version 6.30.0: updater policy files are fail-closed inputs

Version 6.30 treats both active and rollback-paused updater policies as security-sensitive input at every public updater path. Policy reads now reject symbolic links, directories, FIFOs and other special files before opening them; cap input at 64 KiB; and validate the stored Boolean, interval, repository and Claude-command field types. `status`, scheduled `run`, direct update, rollback, reconfiguration and the doctor therefore fail closed instead of following a redirected file, hanging on a pipe or crashing on malformed schema.

Atomic JSON writes now use an unpredictable owner-only temporary file in the destination directory, flush it before replacement and always clean it up. A pre-created legacy `updater.json.tmp` link can no longer redirect policy output into another file. Existing regular policy files remain compatible. `auto-update disable` preflights both active and rollback-paused policies before scheduler mutation, then removes only the exact file identities it inspected; unsafe or concurrently exchanged policy state blocks fail-closed.

### Version 6.29.0: reconfiguration preserves signed-update enforcement

Version 6.29 closes the remaining configuration-time downgrade path in the signed-commit policy. Re-running `auto-update enable` to change an interval or repair a scheduler now resolves the same monotonic active and rollback-paused policy before writing configuration. Omitting `--require-signed-commits` therefore cannot overwrite a stored `true`, and restoring automatic updates after rollback cannot discard the paused requirement.

If either stored policy is malformed, non-Boolean, unreadable, linked, or exchanged during reconfiguration, activation stops before scheduler installation. The active replacement and paused-policy removal are each bound to the exact identities read during monotonic policy resolution, so a concurrent replacement is preserved rather than overwritten or deleted. The deliberate escape path remains explicit and auditable: run `auto-update disable` to remove both policies, then enable again without the signature option.

Regression tests cover interval-only reconfiguration, reactivation from a paused signed policy, preservation of invalid or concurrently replaced policy bytes, linked paused state, and the explicit disable-then-enable reset control.

### Version 6.28.0: signed-update policy cannot be downgraded by omission

Version 6.28 makes the optional signed-commit policy monotonic across every updater entry point. After signature enforcement is enabled, a direct `update` call without `--require-signed-commits` can no longer silently fall back to unsigned mode. The updater resolves the effective policy by combining the caller request with both the active automatic-update policy and the policy paused after a successful rollback; any stored `true` remains authoritative.

Malformed JSON, a non-object policy, or a non-Boolean `require_signed_commits` value now blocks update and rollback fail-closed before candidate testing or active mutation. This prevents values such as the string `"false"` from being interpreted inconsistently. Disabling automatic updates still explicitly removes both stored policies, preserving the existing operator-controlled escape hatch.

Regression tests prove that an unsigned candidate cannot execute its import-time marker through a flagless direct update, that the paused rollback policy reaches the update worker as `true`, and that a type-invalid policy never invokes the worker.

### Version 6.27.0: verify trust before executing candidate code

Version 6.27 closes an updater supply-chain gap in the optional signed-commit policy. Previously, a clean clone ran its repository-owned test suite before `git verify-commit` rejected an unsigned update or rollback target. Test discovery imports Python modules, so a rejected commit could execute code even though it never became active.

When `require_signed_commits` is enabled, both forward update and rollback now resolve and verify the exact checked-out commit immediately after clone or checkout. Only a trusted signature permits test discovery, candidate metadata reads, Claude preflight, fetch, merge, or runtime work. Signature rejection leaves the active checkout and every installed runtime unchanged. The default remains compatible: installations that do not require signed commits continue to test unsigned candidates before activation.

The regression tests place an observable import-time marker inside an unsigned candidate and an unsigned rollback target. Both operations must reject the commit while the marker remains absent, proving that the result is not merely a later rollback after code execution.

### Version 6.26.0: fail-closed Claude preflight before runtime cutover

Version 6.26 closes the split-version window caused by discovering a deterministic Claude plugin failure only after the repository, signer, and MCP had already advanced. When the Claude plugin is installed, the updater now validates the clean temporary candidate with Claude's strict validator, refreshes only the trusted marketplace, and proves exact catalog-version equality while the active checkout and both persistent runtimes are still untouched.

Only a successful preflight permits the fast-forward and runtime restarts. The later plugin-cache step consumes that exact expected-version preflight instead of repeating mutation-prone discovery. Validator failure, marketplace failure, catalog drift, an unavailable Claude executable, or process loss records a degraded retry while preserving the active commit, services, and installed cache. A disappearing plugin between preflight and application also fails closed. Tests prove the preflight never invokes `plugin update`, a rejected candidate does not fetch, merge, restart, or create its new runtime file, and process loss becomes a structured failure instead of crashing the scheduler.

The unavoidable residual race is explicit: Claude's documented update command targets the latest marketplace version rather than a pinned content digest. Final enabled-state, load-error, and exact-version verification therefore remains mandatory after application; any mismatch leaves delivery degraded and fail-closed.

### Version 6.25.0: Claude-native strict validation before update

Version 6.25 closes the schema-authority gap in automatic Claude plugin maintenance. Repository tests can verify the files and the BLUN contracts, but they are not Claude Code's own parser. Before refreshing a marketplace or touching an installed cache, the updater now runs the documented `claude plugin validate <plugin-root> --strict` command against the exact repository candidate that already passed the full test suite.

Any validator error or warning treated as an error blocks before marketplace refresh and before `plugin update`; the previously installed cache remains unchanged and maintenance is reported as degraded. A valid candidate continues through the Version 6.24 trusted-marketplace refresh, exact catalog-version equality check, official user-scope update, and final installed-version, enabled-state, and load-error verification. An already exact healthy cache remains a no-op.

### Version 6.24.0: tested-version marketplace synchronization

Version 6.24 closes a stale-catalog gap in automatic Claude plugin maintenance. Anthropic documents marketplace refresh and plugin update as separate CLI operations: `plugin marketplace update` retrieves version changes, while `plugin update` installs the latest version known to that marketplace. Calling only the latter could therefore leave an old catalog and old hooks in place even though the updater had already tested a newer repository revision.

For an already-installed but stale plugin, the updater now refreshes only `blun-language-tools`, inspects the refreshed public catalog with `plugin list --available --json`, and requires its advertised version to equal the fully tested runtime version before it invokes the official user-scope plugin update. Refresh failure, invalid catalog output, a missing plugin, catalog/runtime drift, update failure, disabled state, load errors, or final version mismatch all remain degraded and fail-closed. An already exact, enabled, error-free cache stays a no-op. The updater still never installs a missing plugin or claims that an existing session has reloaded downloaded hooks.

### Version 6.23.0: service-authoritative session retirement

Version 6.23 handles Claude's `SessionEnd` lifecycle event as an authoritative cleanup boundary. Anthropic documents that this event runs when a session terminates, including `/clear` and switching sessions through interactive `/resume`, and that it is intended for cleanup rather than decision control. The plugin therefore removes the owner-only local epoch and every grant record for that exact session before it contacts the isolated service. Another concurrent session and its grants remain untouched.

The service retires the epoch only when the request names the exact epoch that is still current, then replaces it with an undisclosed random tombstone. A delayed cleanup from an older session lifecycle cannot overwrite a newer `SessionStart` epoch. Restoring a deleted marker and grant afterward remains blocked by the service; a later genuine startup or resume registers a fresh epoch and restores normal one-time delivery. The hook uses a 700 ms service deadline and a one-second command timeout so local fail-closed cleanup completes within Anthropic's documented 1.5-second overall `SessionEnd` budget. It emits no output and cannot pretend to block termination.

### Version 6.22.0: service-authoritative API-failure revocation

Version 6.22 makes `StopFailure` invalidation authoritative at the isolated service instead of relying only on deletion of local hook records. Every failed Claude turn now rotates that session's random epoch through the guard service. All earlier main-agent and subagent delivery grants are therefore invalid even if an old local grant record and its matching epoch marker are later restored. A parallel session retains its independent epoch and grants.

The rotation removes the old local epoch before asking the isolated service to register its replacement and writes the new owner-only marker only after confirmation. If the guard is unavailable, rejects the epoch, or the marker cannot be replaced, the session remains deliberately fail-closed until a later `SessionStart` repairs it. After a successful rotation, a fresh exact response or translation release works normally and remains one-time. The hook still emits nothing because Anthropic documents `StopFailure` output and exit status as ignored.

### Version 6.21.0: invalidate grants after API failure

Version 6.21 handles Claude's `StopFailure` lifecycle event, which Anthropic documents as running instead of `Stop` when a turn ends because of an API error. A rate limit, authentication failure, server error, output-limit failure, or other API failure now removes every unconsumed main-agent and subagent delivery grant belonging to that exact Claude session. A later retry must therefore obtain a fresh response or translation release; another concurrent session remains untouched.

The cleanup is deliberately silent. Anthropic documents that `StopFailure` output and exit status are ignored, so the hook does not pretend it can block or guide Claude at this event. It emits no candidate, rendered API error, or diagnostic detail. The next `UserPromptSubmit`, `Stop`, and `SubagentStop` boundaries remain fail-closed if protected state is unavailable or could not be removed.

### Version 6.20.0: safe recovery after guard-service restart

Version 6.20 lets an already running Claude session recover after the isolated guard service restarts. Anthropic's official [hooks reference](https://code.claude.com/docs/en/hooks) describes `SessionStart` as a session lifecycle event, so restarting an independent local service does not itself create a new Claude startup boundary. Version 6.19 therefore invalidated old grants safely but also left the restarted service without the active session epoch until Claude restarted or resumed.

The service may now recover a missing epoch only inside `authorize_delivery` and only after it has cryptographically verified a fresh response or translation receipt. It never recovers during grant consumption. A forged or rejected receipt cannot enroll a session; a different epoch already registered during the current service boot still blocks; every pre-restart grant remains invalid because its signed service-boot identity changed. The next successful release call restores availability without weakening fail-closed behavior or recording the raw epoch in the audit log.

### Version 6.19.0: service-authoritative session epochs

Version 6.19 closes the remaining two-file replay path in the Claude hook. Version 6.18 rejected an old local grant record after `SessionStart` rotated its epoch marker, but restoring both the record and its matching old marker could recreate the local state. The isolated guard service now registers the active epoch for each hashed Claude session and atomically requires that registered value before issuing or consuming any delivery grant.

Every startup, resume, clear, compaction, or fork therefore replaces the service-authoritative epoch as well as the owner-only local marker. Previously registered epochs cannot be registered again during the same service boot. Restoring both old files, authorizing against an obsolete epoch, replaying an earlier registration, or losing the registration response blocks; another session remains independent. The service retains only session and epoch hashes, and neither the raw epoch nor candidate text enters its audit log. Anthropic's official [hooks reference](https://code.claude.com/docs/en/hooks) documents these `SessionStart` lifecycle sources.

### Version 6.18.0: session-resume-bound delivery grants

Version 6.18 prevents an unconsumed delivery grant from surviving a Claude session restart, `--resume`, `--continue`, `/resume`, `/clear`, or context compaction. Anthropic's official [hooks reference](https://code.claude.com/docs/en/hooks) states that `SessionStart` runs for each of those lifecycle sources, including resumed sessions. The plugin now rotates a cryptographically random delivery epoch on every `SessionStart`, removes the session's outstanding main-agent and subagent records, and requires that epoch before it will authorize any new release.

The isolated service signs only the epoch's SHA-256 binding into each delivery grant and checks the live epoch again during one-time consumption. The raw epoch remains in an owner-only local marker and never enters the grant, audit log, candidate diagnostics, or skill text. A copied pre-resume record, missing marker, unsafe marker permissions, failed rotation, cross-session epoch, or old pre-6.18 record blocks; the final `Stop` and `SubagentStop` checks therefore remain fail-closed even if stale local JSON is restored after resume.

### Version 6.17.0: invalidate grants on every rejected release

Version 6.17 closes the logical-failure half of the stale-grant path. A release tool can execute successfully while returning no usable receipt, while the isolated verifier rejects that receipt, or while delivery authorization becomes unavailable. The synchronous `PostToolUse` hook now clears any earlier grant for the exact session and agent before processing every new release attempt and clears it again on every rejection path. A failed new attempt can therefore never fall back to an older authorization.

The second invalidation is deliberate: Anthropic's official [hooks reference](https://code.claude.com/docs/en/hooks) documents that `PostToolUse` hooks run concurrently for parallel tool calls. Rechecking on rejection ensures that a later failure removes a grant written by an overlapping earlier attempt, while a later successful attempt may still establish its own exact grant. Missing receipts, verifier rejection, verifier outages, protected-state deletion failures, cross-session isolation, privacy-safe diagnostics, and ordinary success all have regression coverage.

### Version 6.16.0: fail closed after release-tool failures

Version 6.16 closes the stale-grant path that appears when Claude's MCP release call fails. Anthropic's official [`PostToolUseFailure` hook contract](https://code.claude.com/docs/en/hooks) can add recovery context alongside the tool error and can return a blocking decision. The plugin now matches only failed `release_response` and `release_translation` calls, immediately removes any earlier unconsumed delivery grant for that exact Claude session and agent, and tells Claude to reconnect and repeat the correct release workflow.

The failure hook never copies the candidate, source, tool error, receipt, or token into its output. It preserves grants belonging to other agents and sessions, ignores unrelated failed tools, and blocks if protected state cannot be invalidated. `Stop` and `SubagentStop` remain the authoritative delivery boundary: a failed release call never creates a grant, and the now-stale earlier text cannot pass afterward. Regression tests prove same-agent invalidation, cross-session isolation, recovery instructions for both release paths, privacy-safe output, and unchanged exact-release success.

### Version 6.15.0: mandatory subagent startup context

Version 6.15 closes an instruction gap between the main Claude session and its subagents. Anthropic's official [hook lifecycle](https://code.claude.com/docs/en/hooks) places `SubagentStart` context before a subagent's first prompt. The plugin now uses that event to tell every subagent that native-language output requires its own fresh `release_response` or `release_translation` grant, bound to that session and agent identity. A subagent no longer has to discover the requirement only after `SubagentStop` rejects its first answer.

`SubagentStart` is guidance, not the security boundary: Anthropic does not allow it to block subagent creation. The existing service-backed `SubagentStop` verification and bounded hard stop remain authoritative. A healthy startup injects the exact release workflow; an unavailable guard injects an explicit fail-closed instruction. Tests prove the correct event-specific output, both release paths, agent-specific wording, and the unavailable-service branch.

### Version 6.14.0: turn-bound delivery grants

Version 6.14 prevents an unconsumed Claude delivery grant from surviving an interrupted turn. Anthropic's official [hook lifecycle](https://code.claude.com/docs/en/hooks) places `UserPromptSubmit` before Claude processes each new turn. The plugin now uses that trusted boundary to invalidate every outstanding main-agent and subagent grant belonging to the current session before the new prompt is processed. A generic response released in an abandoned turn therefore cannot authorize identical text in a later turn.

The added session identifier is only a SHA-256 label, never the prompt or source text. Invalidation scans only hook-state JSON records, preserves labeled concurrent sessions, tolerates unrelated or malformed foreign records, and blocks the current prompt if a matching record cannot be removed. Structurally valid pre-6.14 grant records have no session label and are discarded once during the upgrade rather than trusted across a turn boundary. Regression coverage proves cross-turn replay rejection, same-session and legacy-subagent cleanup, parallel-session isolation, and ordinary release behavior after the boundary.

### Version 6.13.0: bounded fail-closed Stop recovery

Version 6.13 closes a Claude lifecycle bypass caused by repeated Stop-hook rejection. [Anthropic documents](https://code.claude.com/docs/en/hooks) that `stop_hook_active` becomes true when Claude is already continuing because of a Stop hook, while the official [hook troubleshooting guide](https://code.claude.com/docs/en/hooks-guide) explains that Claude Code eventually overrides a hook after repeated consecutive blocks. Returning `decision: "block"` forever was therefore neither reliable enforcement nor reliable recovery.

The mandatory hook now gives Claude one protected correction cycle. A newly released exact response or translation can still pass during that cycle. If `stop_hook_active` is already true and the output remains unverified, both `Stop` and `SubagentStop` return the universal `continue: false` hard stop instead of adding another block. The user-visible stop reason is generic and contains no candidate text, receipt, source, or token. Tests cover the first correction request, the second-attempt hard stop, a successfully corrected signed answer, and the subagent path.

### Version 6.12.0: non-mutating portable verification

Version 6.12 closes a trust-root failure in the portable pre-output verifier. Earlier portable and installed-skill hooks used the signer's load-or-create helper: a missing verifier key could therefore create a new signing key before rejecting the current receipt, and a later signer restart could adopt that unrelated key. Both hooks now only read an existing key, require at least 32 bytes, enforce owner-only permissions on POSIX systems, and fail closed without creating directories or files. The explicit `BLUN_LANGUAGE_GUARD_KEY` compatibility path remains available, but no filesystem fallback may initialize or repair signing state.

Regression tests exercise both shipped hook locations, prove that a missing key remains absent, prove that broadly readable keys block on POSIX, and retain the existing exact-receipt success and edited-target rejection controls. Version 6.11's complete context-bound one-time delivery grants remain unchanged.

### Version 6.11.0: complete delivery-context binding

Version 6.11 closes the final context gap between a successful release tool call and Claude's actual `Stop` or `SubagentStop`. The isolated service now signs the canonical source hash, target hash, exact language, task purpose, content type, short-text review flag, delivery channel, Claude session, agent identity, guard version, service boot, expiry, and nonce into every one-time delivery grant. The stop hook must return that complete context when consuming the grant; any changed, missing, stale, copied, or cross-context value blocks delivery.

The Claude hook stores only the canonical source hash, never the complete translation source. The full source remains bound by the original signed release receipt and is independently verified before the delivery grant is issued. A translation grant therefore cannot be relabeled as a normal response, moved to another locale or content policy, or detached from its source context at the last delivery boundary. Version 6.10's deep health probe and existing one-time, target, session, subagent, restart, and replay protections remain unchanged.

### Version 6.10.0: deep MCP health proof

Version 6.10 closes a false-green health gap. The one-minute monitor no longer accepts a signer heartbeat plus MCP initialization and a matching tool list as proof that the language guard can actually execute tools. The isolated service's authenticated health operation now performs an audit-free response release with correct Swedish Unicode, verifies the resulting purpose-bound signature, and proves that a changed target is rejected. The HTTP probe then performs a real MCP `tools/call` using `validate_text` on `Hälsokontrollen är aktiv.` and requires an exact `PASS` result.

No customer text, token, or synthetic canary is written to the audit log. A broken release/signature path, a gateway that merely advertises tools, or a failed tool dispatcher now makes the health monitor block and enter its existing ordered repair and bounded-backoff path. The integration suite runs this complete chain through temporary TCP signer and authenticated HTTP MCP servers without touching installed services.

### Version 6.9.0: transactional safe rollback

Version 6.9 turns the updater's recorded previous revision into an explicit, fail-closed recovery command. `rollback` accepts only an exact 40-character commit recorded by the immediately preceding successful or degraded update, requires the current `HEAD` to match that update, requires a clean worktree, and proves that the target is an available ancestor. It clones the target locally, runs its complete test suite, enforces the saved signed-commit policy when enabled, and changes the active checkout only after every preflight passes. The rolled-back checkout is tested again and already-installed guard and MCP runtimes must restart and pass their live probes; otherwise the updater restores the forward revision. The final automatic-update pause is bound to the exact active and paused policy identities inspected before candidate execution; concurrent replacements are preserved and trigger forward restoration instead of being overwritten or moved.

Claude adds a necessary safety boundary. Anthropic documents `claude plugin update` as updating to the latest plugin and does not document a version-pinned downgrade. Therefore the command never guesses or edits Claude's cache: if the plugin is installed, its enabled, error-free cached version must already equal the rollback target before Git changes. After success, the operating-system scheduler is removed and its policy is preserved as `updater.rollback-paused.json`, so even an older rolled-back installer cannot immediately reinstall the rejected revision. Existing Claude sessions still require `/reload-plugins` or a restart.

### Version 6.8.0: mandatory plugin-cache health

Version 6.8 extends the one-minute health path to the installed Claude plugin cache because the mandatory `Stop` and `SubagentStop` hooks live there. Once the monitor observes an installed `translate-native@blun-language-tools` plugin, it enrolls that cache and checks its enabled state, load errors, and exact version together with the signer and MCP. A stale or unhealthy enrolled cache blocks the overall health result and receives one official `claude plugin update ... --scope user` repair attempt under the same operation lock and exponential backoff as the services.

Enrollment never installs a missing plugin and never reads or edits Claude's private cache layout. The monitor uses the owner-visible Claude executable recorded at installation or updater setup, calls only the documented `plugin list --json` and `plugin update` commands, and verifies the exact version afterward. A successful cache repair still does not claim that an existing session reloaded its hooks: run `/reload-plugins` or start a new session before relying on the new plugin code.

### Version 6.7.1: self-healing guard stack

Version 6.7 adds an independent one-minute health monitor for the two-process Claude path. It verifies both the isolated signer and the complete authenticated MCP `healthz` → `initialize` → `tools/list` path. If the signer fails, it repairs that dependency first and then rechecks the MCP; if only the MCP fails, it restarts only the MCP. Every repair is followed by a complete end-to-end probe before the state may become `recovered`.

The monitor uses systemd on Linux, a LaunchAgent on macOS, and Task Scheduler on Windows. A shared atomic operation lock prevents it from fighting the updater, and each run makes at most one dependency-ordered repair. Version 6.7.1 replaces the ineffective fixed cooldown with persistent exponential backoff: repeated failed repairs wait 1, 2, 5, 15, and then at most 60 minutes, while health probes continue every minute. A skipped probe does not increase the failure count or postpone the next eligible repair, and a successful end-to-end probe resets the backoff immediately. Its state contains only health booleans, timestamps, counters, and repair labels—never source text, target text, receipts, or credentials. Failure remains fail-closed: the monitor never substitutes a local signer or releases pending output while either process is unhealthy.

Fresh Claude installations enable the monitor automatically. Existing automatically updated installations detect the missing health state on their next scheduler wake-up and install it without waiting for the normal update interval:

```bash
python3 installer/blun_language_guard.py health-monitor install
python3 installer/blun_language_guard.py health-monitor status
python3 installer/blun_language_guard.py health-monitor run
```

`health-monitor remove` removes only the monitor schedule; it preserves both services, all secrets, and user configuration. Before changing the schedule or persisted opt-out, it validates the exact policy and state files and refuses linked, unsafe, malformed, or concurrently replaced state fail-closed.

### Version 6.5: service-owned one-time delivery grants

Version 6.5 removes the local Claude hook record as a trust decision. After `release_response` or `release_translation`, the `PostToolUse` hook sends the complete receipt context to the isolated service. A valid receipt is exchanged for a short-lived signed delivery grant bound to the exact target hash, Claude session, agent or subagent, guard version, service boot, purpose, locale, and expiry.

The owner-only hook file contains the opaque delivery grant, canonical source and target hashes, signed context labels, and authorization time—never the source or target prose. The grant file and service-authoritative session epoch are bounded regular files opened without following links where the platform supports it, checked for owner-only access and stable identity, and replaced through unpredictable exclusive temporary files. At `Stop` or `SubagentStop`, the hook removes the exact inspected record before asking the isolated service to consume the grant for the actual `last_assistant_message` and exact recorded context. The service accepts each nonce exactly once. Copying a consumed record, forging or relabeling local state, racing its replacement, changing the final response, moving a grant to another session or subagent, restarting the signer, or crossing a version boundary now fails closed.

This strengthens the ordinary same-user installation without overstating it. A process that can read the service authentication token, replace managed hooks, or reach the final delivery channel can still bypass workflow enforcement. Use a separate OS identity, container, remote signer, and host-owned delivery credentials for a hostile-process boundary.

### Version 6.4: Claude plugin and mandatory final-response hooks

The repository is now both a Claude Code plugin and a Claude plugin marketplace. The plugin bundles the `translate-native` skill, connects to the persistent HTTP MCP, injects mandatory policy at session start, observes successful release-tool calls, and applies `Stop` plus `SubagentStop` hooks to the actual final response.

The `PostToolUse` hook does not trust the MCP result by appearance. It sends the receipt, exact target, complete source for translations, purpose, locale, and content policy to the isolated verifier. Version 6.5 exchanges a valid result for a service-owned one-time delivery grant rather than trusting the local hook record itself. A missing, stale, replayed, wrong-purpose, or post-release-edited result prevents Claude from stopping and tells it to run the proper release path again.

Install the persistent runtime first, then the marketplace plugin:

```bash
python3 installer/blun_language_guard.py install --target claude
claude plugin marketplace add Maykbiletti/translate-native --scope user
claude plugin install translate-native@blun-language-tools --scope user
```

In Claude's `/plugin` interface, open **Marketplaces → blun-language-tools → Enable auto-update**. Claude then refreshes the marketplace and installed plugin at startup. A changed plugin is activated by `/reload-plugins` or the next session; the independently installed HTTP service continues running during that change.

The plugin's checked-in components are:

- [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json): versioned plugin manifest;
- [`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json): GitHub marketplace catalog;
- [`.mcp.json`](.mcp.json): plugin-scoped persistent MCP connection;
- [`hooks/hooks.json`](hooks/hooks.json): session, release-tool, main-agent, and subagent hooks;
- [`claude_language_hook.js`](integrations/claude_language_hook.js): cross-platform, zero-package verification state machine.

This closes accidental omission and catches an agent that validates one draft but returns another. A forged hook-state file alone no longer passes because the isolated service must consume its signed grant. It is still not a hostile-process boundary: same-user code may be able to read service credentials or disable an unmanaged plugin. For organization-wide enforcement, force-enable the plugin and managed hooks, remove direct delivery credentials from the agent, or place a buffering BLUN host in front of rendered output.

### Version 6.3: persistent Claude MCP

Claude Code no longer needs to keep this guard alive as a child `stdio` process. The installer registers an authenticated, user-scoped Streamable HTTP server at `http://127.0.0.1:47632/mcp`. The endpoint is stateless: every tool call is a separate request, so a disconnected client pipe cannot kill the server or erase its tools. The operating system keeps the process alive and restarts it after a failure. This follows Claude Code's documented [user-scoped HTTP MCP configuration](https://code.claude.com/docs/en/mcp) and the MCP specification's [Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports).

```bash
python3 installer/blun_language_guard.py install --target claude
python3 installer/blun_language_guard.py mcp-service status
python3 installer/blun_language_guard.py doctor
```

Installation safely updates the top-level user entry in `~/.claude.json`, preserves unrelated settings and MCP servers, creates `~/.claude.json.bak`, and removes stale same-name local entries stored under individual projects in that file. This matters because Claude's local and project scopes take precedence over user scope; an old project-specific `stdio` definition can otherwise make the repaired server appear unreliable only in certain repositories. Checked-in `.mcp.json` files remain project-owned and must not define another server with the same name. `doctor` reads each candidate through a bounded no-follow check and fails closed on symbolic links, additional hard links, special files, unsafe permissions, malformed schemas, oversized content, or exchange races instead of silently treating an unreadable configuration as shadow-free.

The exact generated shape is also available as [`claude-http.example.json`](mcp-server/claude-http.example.json) for inspection. Let the installer write the machine-specific absolute helper path instead of copying the example by hand.

The Claude entry uses [`mcp_auth_headers.py`](integrations/mcp_auth_headers.py) as `headersHelper`. Claude runs that helper again at connection time and after an authentication retry, so the bearer token remains in an owner-only file instead of being copied into configuration. The HTTP server binds only to loopback, validates browser origins, requires authentication, rejects oversized or invalid requests without exiting, accepts UTF-8 BOM input, and exposes an authenticated `/healthz` probe covering the complete path to the isolated guard service.

The persistent transport improves availability; it does not turn MCP instructions into a security boundary. The trusted host must still intercept output and fail closed. If the HTTP service or isolated signer is unavailable, delivery remains blocked rather than falling back to local signing or raw text.

### Version 6.2: isolated runtime enforcement

Version 6.2 moves signing and final verification into [`guard_service.py`](integrations/guard_service.py), a dedicated loopback service. The MCP process and host adapters receive only a service endpoint and an authentication token; the untrusted agent child receives neither the signing key nor the service token. The service accepts UTF-8 with or without a BOM, signs releases, verifies the exact envelope at delivery time, and appends a content-free audit record containing only hashes, route metadata, guard version, and finding codes.

The audit log and its interprocess lock now use protected append-only handles. They are created exclusively with mode `0600`, refuse symbolic links, additional hard links, FIFOs, non-owner files, and paths writable by another account, and verify that the named file still matches the open descriptor before and after locking or appending. A substituted or exchanged audit path therefore blocks the release without modifying its target. The authenticated health self-test inspects both paths without creating a canary record, so the monitor cannot report green while real releases would fail at the audit boundary; existing content-free `0644` logs remain readable and append-compatible because only owner write access is required.

The signing key is treated as protected trust-root state. Signer and verifier paths accept only bounded, owner-only regular files, refuse symbolic links, open without following links where supported, and compare file identity across inspection and reading. First creation reserves the final path exclusively and requests owner-only mode `0600` where POSIX permissions apply; the former predictable `.tmp` name is never touched, and a concurrent creator can neither replace an existing key nor redirect initialization through a prepared link.

The isolated service authentication token now uses the same protected-state contract everywhere it is consumed: the signer, MCP process, mandatory host delivery command, Claude hooks, BLUN Code adapter, installer probe, and doctor accept only a bounded regular file, require owner-only access where POSIX permission bits apply, and verify its identity before and after reading. Installation reserves the final token path exclusively, requests owner-only mode `0600` on POSIX systems, and never touches the former predictable `.tmp` name. A linked, oversized, broadly readable, replaced, or malformed token therefore fails closed before any request reaches the signer; direct environment-token deployments remain compatible.

The persistent HTTP MCP bearer token follows that protected-file contract independently. The gateway, Claude `headersHelper`, installer health probe, and doctor accept only a bounded owner-only regular token, open it without following links, and verify the same file identity throughout the read. Installation reserves `mcp-http.token` directly with exclusive creation and owner-only mode instead of writing through the former predictable `.tmp` path. An unsafe token therefore blocks before the loopback MCP starts or receives a health request, while an existing valid token continues to survive reinstall and rotation is picked up by the headers helper on the next reconnect.

The mandatory `delivery-policy.json` is protected at each trust decision as well. The host delivery boundary, Claude hooks, installer, and doctor accept only a bounded owner-only regular JSON file, open it without following links, compare its identity before and after reading, and validate the fail-closed delivery and isolated-service fields. A linked, oversized, broadly readable, malformed, or exchanged policy blocks before model output, command installation, key creation, or service access; an absent policy still preserves the existing first-install and explicitly configured local-verifier paths.

Health-monitor policy and backoff state use the same protected-file discipline. The installer accepts only bounded owner-only regular JSON files, opens them without following links where supported, verifies stable identity across the complete read, and validates the persisted Boolean, integer, string, and repair-list fields. Unsafe health state blocks status, repair, and update candidate execution without restarting services, resetting backoff, replacing a linked path, or changing its target. Missing files retain the existing first-run migration behavior, valid owner-only files remain compatible, and POSIX permission checks remain disabled on Windows where those mode bits are not authoritative.

Health-monitor activation is also bound to the exact policy identity inspected after its initial health probe. A policy that appears or changes before scheduler installation blocks without touching the scheduler. If an exchange races with scheduler activation, the replacement is preserved, the newly installed schedule is removed, and activation reports a fail-closed error instead of overwriting concurrent operator state.

The minutely monitor applies the same identity binding when it first observes an installed Claude plugin and automatically enrolls that cache in mandatory health checks. A policy exchanged while Claude's status command is running survives unchanged; enrollment, plugin repair, and health-state publication stop fail-closed instead of replacing the operator's newer policy.

Every minutely health-state transition is likewise bound to the exact backoff file inspected at run start. An exchange discovered after probing blocks before a service or plugin repair; an exchange during a repair preserves the replacement and prevents the stale result from being published. This keeps concurrent operator state and a newer backoff authoritative without weakening the existing one-repair-per-run limit.

The monitor also keeps its initially inspected health-policy identity authoritative for the complete run. A policy exchanged during signer, MCP, or Claude probing blocks before any repair; an exchange during a repair prevents later dependent repairs and stale health-state publication. Automatic Claude enrollment refreshes the expected identity only after its own protected policy replacement, so the compatible first-enrollment path remains available while concurrent operator changes remain authoritative.

The updater's recorded state is protected independently from its policy. `doctor`, `auto-update status`, scheduled checks, direct updates, and rollback now read `update-state.json` through a bounded owner-only regular-file path, reject links and exchanged identities, and validate commit hashes plus every security-relevant persisted type. Unsafe state blocks before Git commands or candidate code can run and is never printed or replaced through that read path. A missing state remains valid before the first successful update, while rollback continues to require a complete exact state record.

Update and rollback now retain that initially inspected state identity for the complete maintenance operation. Candidate activation stops if another process replaces the state during preflight or fetch, rollback restores the forward revision if the state changes during runtime verification, and every final status write rechecks the same identity immediately before atomic replacement. Concurrent recovery decisions therefore survive unchanged instead of being overwritten by stale success, degraded, or rolled-back reports; the absent first-run state remains compatible.

Forward updates now retain the initially inspected health-policy and backoff-state identities as well. Scheduler activation, healthy-state initialization, and automatic Claude plugin maintenance stop when either protected file is exchanged during the update. Every updater-owned health write rechecks both identities immediately before atomic replacement and refreshes only the identity produced by its own successful write. A concurrent opt-out therefore survives unchanged and removes the schedule activated by the stale updater pass; other replacement policies and newer backoff decisions remain untouched while the update records a degraded retry.

The installer now creates and starts the service automatically through systemd user services on Linux, a LaunchAgent on macOS, or Task Scheduler on Windows:

```bash
python3 installer/blun_language_guard.py install
python3 installer/blun_language_guard.py service status
python3 installer/blun_language_guard.py doctor
```

Linux systemd units and macOS LaunchAgent definitions are installed through a protected atomic boundary before either service manager is called. Existing definitions must be bounded single-link regular files owned by the current user and not writable by another account; symbolic links, hard links, special files, and concurrent replacements block without altering their targets or activating a service. The installer also traverses every service-directory component below the user home without following links, rejects directories writable by another account, and creates and replaces definitions relative to a held directory handle. A concurrently exchanged parent therefore cannot redirect the write or activate a detached definition. Newly written definitions use owner-only permissions. Resetting updater, health-monitor, or MCP autostart keeps the same protected directory handle from marker preflight through identity-checked removal, so linked, broadly writable, or exchanged parents cannot redirect the cleanup. The definition itself must still pass no-follow and stable-identity checks and contain service-specific BLUN markers. Windows Task Scheduler behavior is unchanged.

Use `service start` or `service stop` for explicit lifecycle control. `install --no-service-autostart` exists for packaging and tests, but a production host must not deliver model output in that state. A per-user service prevents accidental key exposure to child processes; resisting a hostile same-user agent still requires a separate service account, container, or remote signer with filesystem and channel credentials denied to the agent.

Two host adapters are included:

- [`node-language-guard.js`](integrations/adapters/node-language-guard.js) provides strict routing, envelope parsing, isolated verification, and verify-before-send Telegram delivery for Node.js hosts.
- [`blun-code-language-guard.js`](integrations/adapters/blun-code-language-guard.js) migrates the installed BLUN MCP entry into BLUN Code's encrypted MCP store, buffers model text so an unsigned draft cannot leak through streaming, and releases only the verified target.

The legacy BLUN MCP file is a security-relevant migration input because it selects the isolated endpoint and service-token path. Installer and BLUN Code therefore accept only a bounded, single-link regular `~/.blun/mcp.json` owned by the current user and not writable by another account. Both consumers open without following links where supported and verify stable identity across the complete read. The installer preserves unrelated servers, writes its backup and replacement atomically as owner-only files, and rechecks the original immediately before replacement. A symbolic link, hard link, special file, oversized or malformed document, unsafe permissions, or exchange race blocks before the encrypted store or configuration is changed; existing safe `0644` files remain compatible.

Claude's user-scoped `~/.claude.json` now follows the same protected migration boundary. Installation preflights the bounded owner-controlled single-link file before changing any skill or runtime, then preserves unrelated settings while atomically writing an owner-only backup and replacement. The final replacement rechecks the exact file identity, so links, special files, unsafe write permissions, excessive size, malformed JSON, and concurrent exchange all block without overwriting the substituted target or losing a concurrent Claude change. `doctor` uses the same protected reader, while existing safe `0644` configurations remain compatible.

The trusted router uses structured job metadata, never the agent's claim. A source-bearing or explicitly translated job takes `release_translation`; an ordinary reply takes `release_response`. Contradictory metadata, `auto`, `all`, missing translation source, raw prose, unknown envelope fields, an invalid receipt, an unavailable service, or a sender invocation before verification all block.

Free-form text alone cannot provide non-bypassable task classification. A host that offers translation through chat must set `languageGuardTaskKind: translation`, capture the complete source independently as `languageGuardSourceText`, and set the exact target language. If that metadata is absent, the BLUN adapter instructs the agent not to perform a translation through the response route. See [`BLUN_CODE_INTEGRATION.md`](docs/BLUN_CODE_INTEGRATION.md) for the runtime contract and residual limits.

## Version 5: BLUN Language Gateway

Version 5 makes the host—not the agent—the final authority. Skills and MCP tools can be forgotten or skipped. A mandatory gateway intercepts the candidate output and releases it only after validation produces a signed receipt for the exact source, target, and locale.

```text
User → Agent → intercepted candidate → BLUN Language Gateway
                                      ├── PASS + receipt → release
                                      └── BLOCK          → revise or stop
```

Use the portable gateway with JSON on stdin:

```bash
python3 integrations/language_gateway.py < release-request.json
```

Strong enforcement requires the gateway and signing key to run outside the agent's writable sandbox, ideally as a separate OS user, container, or remote service. If the agent can replace the gateway or read its key, the installation is advisory—not non-bypassable. CLI adapters must capture final output before it is printed; API gateways must withhold the HTTP response; CI must require the check before merge and deployment.

### Automatic safe updates

Enable the operating-system scheduler once:

```bash
python3 installer/blun_language_guard.py auto-update enable --interval-hours 24
python3 installer/blun_language_guard.py auto-update status
```

Linux uses a user-level systemd timer, macOS a LaunchAgent, and Windows Task Scheduler. Each scheduled wake-up checks whether the configured interval is due. A candidate checkout is tested before installation, the update is fast-forward-only, post-update tests run again, and the previous revision is retained for rollback. When Claude is installed, an update also installs or refreshes the persistent HTTP MCP, its dynamic-header helper, its autostart service, and the user-scoped Claude entry before marking the runtime update successful. If activation fails, cleanup is bound to the exact post-install identity of each MCP command, bearer token, and Claude configuration. A path that appeared or changed concurrently is preserved and makes rollback report failure instead of deleting operator-owned state; an existing Claude configuration is restored through an unpredictable atomic temporary file. The repository reset is likewise bound to the exact clean candidate revision: parallel edits or a new commit block reset, cleanup, and secondary restarts without moving the changed checkout. Security-sensitive deployments can require trusted Git commit signatures:

```bash
python3 installer/blun_language_guard.py auto-update enable --require-signed-commits
```

Version 6.6 also coordinates Claude's plugin cache. When automatic updates are enabled, the owner-visible Claude executable path is recorded so an OS scheduler with a smaller `PATH` invokes the same CLI. If `translate-native@blun-language-tools` is already installed at user scope, the updater refreshes its marketplace, requires the catalog version to equal the tested runtime, runs Claude's official non-interactive `plugin update` command, and verifies the exact installed version through `plugin list --json`. A missing plugin is never installed without consent. A plugin or marketplace failure leaves the already-tested runtime and fail-closed MCP active, records a `degraded` updater state, returns nonzero, and retries on the next scheduled wake-up instead of waiting for the normal interval. Version 6.7 uses the same degraded retry path for a health-monitor installation failure and shares an operation lock between updates and repairs. Version 6.8 enrolls an observed installed cache in the one-minute monitor, so disabling it, load errors, or later version drift can no longer leave the services green while the mandatory hooks are unhealthy. A successful cache update still requires `/reload-plugins` or a new Claude session because active sessions retain their previously loaded hook paths.

To return to the exact revision saved by the last update, synchronize an installed Claude plugin to that target version first, make sure the checkout is clean, and run:

```bash
python3 installer/blun_language_guard.py rollback
```

Use `--require-signed-commits` to require a trusted signature even when the saved updater policy did not. The command never selects an arbitrary revision, never downgrades a plugin through undocumented cache manipulation, and never overwrites local changes. A successful rollback pauses scheduled updates; inspect the result, then run an explicit `update` followed by `auto-update enable` when you intentionally want to resume the forward line.

The authoritative plugin version lives only in `.claude-plugin/plugin.json`; the marketplace entry deliberately omits a duplicate version field. Claude uses the manifest version as its cache key, avoiding two version declarations that can drift apart.

Third-party marketplace auto-update is disabled by default in Claude. Users may enable it in the marketplace UI as an additional startup check; the operating-system updater no longer depends on that optional setting. Other platform-native plugin stores remain controlled by their host platform.

BLUN Code is supported explicitly. Installation creates the BLUN skill symlink and safely merges `blun-language-guard` into the protected `~/.blun/mcp.json`, preserving the other MCP servers and writing `mcp.json.bak` atomically before a change. BLUN Code must be restarted once after initial installation; subsequent repository updates are visible through the symlink automatically.

### Production regressions fixed in Version 5

- Page-sized releases are covered by a regression test above 7,000 characters with a one-second local execution budget.
- MCP JSON input accepts the UTF-8 BOM frequently emitted by Windows tooling.
- Long Swedish, German, Spanish, Czech, and Catalan targets receive a language-character profile check that catches wholesale ASCII folding even when no word appears in a small substitution list.
- The Swedish BLUN ASCII-folding regression was found by **Angel** and is retained under her name in the permanent evaluation corpus.

### Version 5.1: short copy and transport-safe identity

Titles, meta descriptions, and UI strings below 200 characters never receive a deterministic `PASS` from character profiles or substitution lists. The gate always returns `REVIEW_REQUIRED` until an independent native review sets `short_text_reviewed: true`; that decision, together with `content_type`, is cryptographically bound into the receipt. This remains true even when the short text still contains some native characters, preventing one surviving `å`, `ä`, or `ö` from hiding another destroyed word.

Text identity now distinguishes transport differences from corruption. Canonical hashes remove a leading UTF-8 BOM, normalize CRLF and lone CR to LF, and normalize Unicode to NFC. Mojibake and actual character changes remain different and invalidate the receipt.

Both portable commands are now present inside the installable skill as well as the repository integration layer:

- `translate-native/scripts/language_gateway.py`
- `translate-native/scripts/pre_output_guard.py`

Symlink installations receive these files with the next automatic update; no manual copying is required.

### Version 5.2: measurable evidence beats self-attestation

Version 5.1 correctly raised a short-copy gate but incorrectly allowed the same caller to declare both `content_type` and `short_text_reviewed`. Those values are not independent evidence and are no longer a security boundary.

Version 5.2 measures conventional ASCII-folding pressure for German, Swedish, Danish, and Norwegian on every target, regardless of length or declared content type. Measurable folding findings cannot be overridden by `short_text_reviewed: true` or `content_type: prose`.

Version 5.2.1 removes German `ss` from that measurement. Unlike `ae`, `oe`, and `ue`, `ss` is frequently correct native spelling (`wissen`, `dass`, `interessiert`) and cannot be classified as a `ß` replacement without lexical and locale context. The guard deliberately leaves cases such as `Grösse` to a future `de-DE`/`de-AT`/`de-CH` dictionary-aware check instead of creating a broad false positive.

### Version 5.3: quantity is part of integrity

`translation_guard.py` now measures linguistic volume in addition to tags and protected tokens. It compares total Unicode letter/number volume, non-empty linguistic segment counts, and aligned segment coverage for text, JSON/ARB, HTML, XML/XLIFF/Android resources, PO, Apple strings, and subtitles. Script-aware thresholds allow naturally compact CJK translations while blocking major omissions such as a 64-unit target derived from a 224-unit source.

A successful deterministic guard now says exactly what it proves: measurable structure, protected tokens, linguistic volume, and Unicode integrity. It explicitly does **not** prove semantic fidelity, true completeness, or native quality. A literal translation can have the right length and still fail the native-language gate.

Version 5.3.1 also makes the volume check unconditional inside the mandatory MCP `release_translation` path. Format detection is derived from the source syntax rather than a caller-supplied checkbox, so truthful-looking attestations cannot release a measurably truncated target. Structured CLI validation remains required for exact tag, key, placeholder, and technical-value integrity.

Version 5.3.2 makes every MCP dependency resolve relative to the installed script itself. The server no longer assumes the repository's `translate-native/scripts` directory layout, and an isolated-install regression test starts the copied server from the exact flat `scripts/` layout used by installed skills.

Version 5.3.3 blocks substantial unchanged targets. When source and target remain identical after transport-only BOM, newline, surrounding-whitespace, and NFC normalization, a source of at least 200 characters fails both the CLI and mandatory MCP release with `source-target-identical`. Short shared terms such as `BLUN King` and `E-Mail` remain valid. The comparison covers the complete input—not only `<main>` or another convenient content subtree.

Version 5.3.4 closes the structured-file segment gap. Human-language values in JSON/ARB, HTML, XML/XLIFF/Android resources, PO, Apple strings, subtitles, and plain text are compared independently. An unchanged segment of at least 24 linguistic units now fails the CLI and mandatory MCP release, even when every other value was translated. JSON keys are aligned independently of property order; other structured formats use cross-target segment identity, so swapping two unchanged HTML or XML values cannot bypass the gate. Copyright and rights notices receive no automatic fixed-content exemption: an unchanged copyright-marked segment is blocked even below the normal segment threshold. Short product names such as `BLUN King` remain valid. A legitimate fixed legal line requires explicit human handling outside the automatic release gate; it is never silently passed.

Read the diagnostic text, not only the exit code. A blocked identity comparison must explicitly report `target is unchanged` or `linguistic segment is unchanged`; JSON findings name the exact path such as `$.hinweis`. The structural translation guard reserves exit code `1` for evaluated content that was blocked and returns `2` when an input file cannot be read. A missing path reports `cannot read file` and is not evidence that the identity detector fired. Tests assert both the expected result and the expected reason.

Other scripts cannot always be reconstructed from stripped ASCII without a dictionary or native model. The guard reports only what it can measure and never claims that this heuristic proves correct spelling. Strong independence still requires the external Language Gateway and reviewer to run outside the releasing agent's authority.

## Version 4 foundation: signed release receipts

Version 4 turns the executable MCP gate into a signed, independently verifiable release system. The skill remains responsible for meaning, native rewriting, locale fit, and orthography. The server blocks deterministic defects and issues a cryptographic receipt bound to the exact source, target, locale, version, issue time, and expiry.

```text
Translation request
        ↓
translate-native skill
        ↓
Native pass → fidelity pass → integrity pass
        ↓
release_translation MCP tool
        ↓
BLOCK → revise and repeat
PASS  → signed receipt → verify receipt → deliver
```

The gate checks UTF-8/Unicode integrity, NFC normalization, script identity, balanced bidirectional isolates, dangerous overrides, frequent ASCII substitutions, optional terminology glossaries, and all seven mandatory attestations. Edited, expired, forged, wrong-locale, or wrong-version receipts fail verification.

### Install, update, and diagnose

```bash
python3 installer/blun_language_guard.py install
python3 installer/blun_language_guard.py doctor
python3 installer/blun_language_guard.py update
```

Installation uses atomic symlinks for Codex and Claude Code and refuses to overwrite existing non-symlink skill folders. Each update reserves an unpredictable staging symlink exclusively, preserves legacy and colliding staging paths, rechecks the destination identity immediately before cutover, and cleans up only its own staging link. It installs `~/.local/bin/blun-language-deliver`, the isolated service command, owner-only key and service-token files, autostart configuration, a content-free audit path, and a fail-closed policy; writes a mergeable MCP snippet without overwriting unrelated host configuration; and merges the BLUN MCP entry safely. Updates are cloned and tested before the active checkout is fast-forwarded, then the service is restarted and health-checked; a failed restart rolls the checkout back. `doctor` checks the delivery command, service health, secret permissions, mandatory policy, test suite, live MCP tools, signed receipts, and updater heartbeat.

The portable fail-closed hook is [`pre_output_guard.py`](integrations/pre_output_guard.py). It accepts `task_kind`, target, locale, receipt, and the complete source for translations as JSON on stdin and exits nonzero when verification fails. It only reads an existing owner-only verification key and never creates or repairs signing state. Host-specific adapters must pass the candidate output into this contract; a host hook that exposes no candidate text cannot enforce output validation.

### Supported structured formats

- JSON and ARB;
- HTML including linguistic metadata and JSON-LD linguistic fields while protecting schema, URLs, types, code, and placeholders;
- XML, Android resources, and structurally equivalent XLIFF documents;
- PO/POT catalogs;
- Apple `.strings`;
- SRT, VTT, and ASS subtitle timing;
- ICU placeholders and plural/select contracts inside supported containers.

See [`PREMORTEM.md`](docs/PREMORTEM.md) for the failure modes, mitigations, and proof required before calling this system production-ready.

No deterministic linter can prove that prose is genuinely native. That is why the MCP server supplements the skill's native-language judgment instead of pretending to replace it.

### Start the MCP server

For Claude Code, use the persistent runtime shown in Version 6.3 together with the current Version 6.155.0 plugin. The HTTP MCP remains available in every project through user scope, while the plugin adds the mandatory lifecycle hooks and the operating-system monitor repairs its service path and enrolled plugin cache. Check the runtime at any time with:

```bash
python3 installer/blun_language_guard.py mcp-service status
claude mcp get blun-language-guard
```

For other clients, the zero-dependency `stdio` transport remains available as a compatibility fallback:

```bash
python3 translate-native/scripts/blun_language_guard.py serve
```

Copy [`mcp-config.example.json`](mcp-server/mcp-config.example.json), replace the absolute path, and merge the `blun-language-guard` entry into the MCP configuration used by that agent CLI. Do not use the `stdio` fallback for Claude after installing Version 6.3; a higher-precedence project or local entry with the same name can shadow the persistent user server.

Then copy the rules in [`AGENT_RULES.md`](integrations/AGENT_RULES.md) into the host's always-on instruction file:

- Codex: repository or global `AGENTS.md`;
- Claude Code: `CLAUDE.md`;
- another MCP-compatible agent: its equivalent persistent instruction file.

This combination matters. A skill can fail to trigger, and an MCP tool can remain unused. The persistent rule requires `release_response` for ordinary answers and both the `translate-native` workflow and `release_translation` for translations. The trusted host gateway remains the final enforcement boundary.

### Validate from the terminal

The same engine can be used in hooks, CI, wrappers, or pre-publication scripts:

```bash
python3 translate-native/scripts/blun_language_guard.py validate --language sv-SE target.txt
```

Exit code `0` means the deterministic checks passed. Exit code `1` means delivery must stop. Semantic and native-quality review remains mandatory even after exit code `0`.

## Native examples

| Target | Native result |
| --- | --- |
| Swedish | `Om du redan har betalat behöver du inte göra något mer.` |
| Simplified Chinese | `你确认前，我们不会分享任何内容。` |
| Catalan | `No es compartirà res fins que ho confirmis.` |
| Basque | `Dagoeneko ordaindu baduzu, ez duzu beste ezer egin behar.` |
| Czech | `Pokud jste již zaplatili, nemusíte nic dalšího dělat.` |
| Spanish | `Si ya has pagado, no tienes que hacer nada más.` |

These are examples, not the boundary of the skill.

## Grammatical is not native

The skill now explicitly rejects agent-written copy that is grammatically correct but still sounds translated. Agents must inspect collocations, parallel structure, paragraph flow, register, unnecessary source-language borrowings, and vague AI filler—not just spelling and syntax.

The Swedish BLUN regression case captures the difference:

| Agent wording | Native review |
| --- | --- |
| `desktop- och mobilprogramvara` | `programvara för datorer och mobila enheter` |
| `fördela uppgiften på ett smart sätt` | `fördela arbetet mellan de modeller som passar bäst för uppgiften` |
| `fördela uppgiften till den modell som passar bäst` | `automatiskt välja den modell som passar bäst för uppgiften` |

All three agent formulations are understandable. They still fail because a native editor would recast them for publication. The complete candidates, defect analyses, native rewrites, and language-independent review procedure live in [`translationese-review.md`](translate-native/references/translationese-review.md).

## The translation contract

Every result passes seven gates:

1. **Meaning** — claims, relationships, conditions, and implications remain equivalent.
2. **Completeness** — nothing is lost, duplicated, or invented.
3. **Precision** — negation, modality, quantities, entities, and terminology remain exact.
4. **Nativeness** — calques, source syntax, and translationese are removed.
5. **Fit** — locale, script, register, audience, tone, and medium are right.
6. **Integrity** — placeholders, keys, links, markup, code, and structure survive intact.
7. **Orthography** — spelling, diacritics, punctuation, spacing, and Unicode are native.

Version 2 deliberately separates judgment into two passes: a target-only native edit that cannot lean on the source wording, followed by a source-aware fidelity audit that accounts for every claim and constraint. Publication-grade, long-form, and uncertain work can be routed through an independent defect review before release.

## i18n without i18n language

JSON, YAML, XML, PO, ARB, ICU MessageFormat, Android resources, Apple strings, Markdown, and HTML are containers. They do not excuse robotic prose.

```json
{
  "welcome": "Ongi etorri, {name}!",
  "upload": "Kargatu {{count}} fitxategi <strong>{project}</strong> proiektura.",
  "help": "Informazio gehiago: https://example.com/help"
}
```

The key structure stays fixed. The Basque values read naturally. Every placeholder, URL, and HTML tag remains protected.

## Install

Clone the repository:

```bash
git clone https://github.com/Maykbiletti/translate-native.git
```

Copy the `translate-native` directory into the skill directory used by your compatible agent platform, or load its [`SKILL.md`](translate-native/SKILL.md) according to that platform's skill instructions.

Invoke it explicitly:

```text
$translate-native
```

Direct skill address:

```text
https://github.com/Maykbiletti/translate-native/tree/main/translate-native
```

## Connect a website-localization provider

The production-oriented website pipeline plans one job per locale, processes
each through separate transcreation, source-blind native review, and
source-aware fidelity review stages, and remains vendor-neutral. A host can now
connect its own LLM or model gateway through the bundled request-bound HTTP
adapter. The public protocol, authentication boundary, idempotency rules,
response schemas, and fail-closed behavior are documented in
[`docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md`](docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md).

The same pipeline can connect its independent quality-evidence service through
the separate request-bound HTTPS adapter documented in
[`docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md`](docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md).
It sends exactly one complete source/candidate pair for one leased locale,
binds request and worker-result hashes end to end, and leaves all retries to the
durable evidence queue.

The adapter is public and contains no fixed provider, brand, product, price, or
credential. Passing transport tests does not establish native-language quality
or superiority over another translation system; those claims require the
separate review and blinded benchmark evidence described in
[`docs/WEBSITE_LOCALIZATION.md`](docs/WEBSITE_LOCALIZATION.md).

## Protect machine-readable content

The zero-dependency guard compares source and target files:

```bash
python3 translate-native/scripts/translation_guard.py source.md target.md
python3 translate-native/scripts/translation_guard.py source.json target.json --format json
python3 translate-native/scripts/translation_guard.py source.html target.html --format html
python3 translate-native/scripts/check_diacritics.py --language sv target.md
```

It blocks delivery when it detects:

- missing, added, or renamed placeholders;
- changed URLs, email addresses, code, HTML tags, escapes, or format tokens;
- changed JSON keys, hierarchy, arrays, scalar types, or non-string values;
- changed ICU argument names, formatters, selectors, or number signs;
- changed HTML structure, technical attributes, comments, scripts, or styles while still allowing native translation of linguistic accessibility attributes;
- target text that is not valid UTF-8 and Unicode NFC.

The guard protects structure. The agent's seven-pass review protects meaning and native quality.

The diacritics linter additionally catches frequent ASCII substitutions such as `schoen`, `forstar`, `informacion`, and `cestina` while leaving code, URLs, and other protected technical spans alone. It is a deterministic warning system, not a finite definition of any language; the built-in orthography gate remains mandatory for every script worldwide.

Language tags without a deterministic substitution list, such as `en`, are accepted. The linter still checks UTF-8 and Unicode NFC, prints that no language-specific diacritics rules apply, and leaves the mandatory native-orthography review in force.

For complete HTML pages, linguistic metadata may change: descriptions, keywords, application names, Open Graph titles/descriptions, and Twitter titles/descriptions are treated as translatable text while their placeholders remain protected. Technical metadata such as viewport settings, encodings, URLs, and unrelated `content` attributes remain fixed.

## Evidence, not dataset worship

| Source | Best use | Warning |
| --- | --- | --- |
| [Language communities and authorities](translate-native/references/native-translation-standard.md) | Orthography, terminology, accepted standard | Prefer the requested community's own convention |
| [Unicode CLDR](https://cldr.unicode.org/) | Locale IDs, formats, plurals, exemplar characters | Locale data is not prose guidance |
| [Unicode Normalization](https://unicode.org/reports/tr15/) | Canonical Unicode normalization | NFC does not prove correct spelling |
| [W3C Language Enablement](https://www.w3.org/International/typography/gap-analysis/language-matrix.html) | Script layout and typography | Web support data is not a dictionary |
| [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry) | Language, script, and region tags | Tags identify a target; they do not translate it |
| [Leipzig Corpora Collection](https://cls.corpora.uni-leipzig.de/) | Native usage and collocations | Check domain and date |
| [FLORES+](https://huggingface.co/datasets/openlanguagedata/flores_plus) | Multilingual evaluation | It is an evaluation set, not training data |
| [OPUS](https://opus.nlpl.eu/) | Supporting parallel examples | Large corpora can contain literal or noisy translations |

Hugging Face is a useful distribution platform, not a quality certificate. Provenance, curation, locale, license, domain, and intended use still matter.

## Repository structure

```text
translate-native/
├── SKILL.md
├── agents/
│   └── openai.yaml
├── assets/
│   └── icon.svg
├── references/
│   ├── native-translation-standard.md
│   ├── native-orthography.md
│   ├── evaluation-protocol.md
│   ├── translationese-review.md
│   └── structured-content.md
└── scripts/
    ├── translation_guard.py
    ├── check_diacritics.py
    └── blun_language_guard.py
```

The MCP configuration example, persistent CLI rules, automated tests, and GitHub Actions workflow live at repository level.

Machine-readable failure cases live in [`evals/regressions.jsonl`](evals/regressions.jsonl). They cover Swedish translationese and model selection, German umlauts, Spanish punctuation and accents, Czech and Catalan orthography, Vietnamese tone marks, Chinese and Arabic native scripts, and Ukrainian language identity. They are regression examples, never a language allowlist.

## Test

```bash
python3 -m unittest discover -s tests -v
```

The suite covers protected text, sentence punctuation after URLs, JSON structure and types, ICU plural/select syntax, safely translatable HTML attributes, HTML/code tampering, Unicode normalization, common missing diacritics in German, Spanish, and Czech, technical-span protection, the combined language-and-orthography contract, repository agent instructions, and both Swedish agent-copy regression cases.

## Design principle

Translation is not token replacement. It is constrained re-authorship: the same meaning, rebuilt inside another language's own system.

That standard is universal. Confidence is not.

## License

Released under the [MIT License](LICENSE).

---

<div align="center">

### Built for every language that people call home.

**BLUN**

*Get it done with BLUN.*

</div>
