blun-king-cli 9.1.597 → 9.1.600
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +17 -1
- package/agent-spine-plugin/CHANGELOG.md +1 -1
- package/agent-spine-plugin/docs/host-integration.md +1 -15
- package/agent-spine-plugin/docs/preflight-recall.md +1 -1
- package/agent-spine-plugin/scripts/check-install.js +1 -6
- package/agent-spine-plugin/scripts/hermetic-process.js +8 -0
- package/agent-spine-plugin/scripts/release-check.js +2 -3
- package/agent-spine-plugin/scripts/run-tests-hermetic.js +8 -11
- package/agent-spine-plugin/src/hook.js +40 -40
- package/agent-spine-plugin/src/lib/briefing.js +6 -3
- package/agent-spine-plugin/src/lib/hook-context.js +63 -64
- package/agent-spine-plugin/src/lib/hook-output.js +115 -94
- package/agent-spine-plugin/src/lib/hook-timeline.js +20 -11
- package/agent-spine-plugin/src/lib/host-instruction-budget.js +8 -14
- package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +0 -7
- package/agent-spine-plugin/src/lib/pre-answer-timeline-recall.js +104 -0
- package/agent-spine-plugin/src/lib/session-timeline-codex.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-enrollment-source.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline-enrollment-storage.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-enrollment-transport.js +0 -2
- package/agent-spine-plugin/src/lib/session-timeline-enrollment.js +0 -22
- package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-prior.js +42 -50
- package/agent-spine-plugin/src/lib/session-timeline-provider.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline-query.js +0 -1
- package/agent-spine-plugin/src/lib/session-timeline-sid-acl.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-source.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline-transport.js +0 -8
- package/agent-spine-plugin/src/lib/session-timeline-windows-acl.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline.js +370 -408
- package/agent-spine-plugin/src/lib/source-roots.js +26 -16
- package/agent-spine-plugin/src/lib/timeline-user-feedback.js +0 -1
- package/bin/core-bootstrap.js +18 -10
- package/bin/launcher-mode.js +5 -0
- package/bin/launcher-runtime.js +27 -0
- package/bin/verify-bundled-agent-sources.cjs +28 -2
- package/blun.mjs +798 -143
- package/bundled-agent-sources.json +192 -155
- package/package.json +1 -1
- package/standard-skills/translate-native/README.md +1334 -1
- package/standard-skills/translate-native/SKILL.md +1 -1
- package/standard-skills/translate-native/VERSION +1 -1
- package/standard-skills/translate-native/docs/PREMORTEM.md +901 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION.md +208 -41
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_API.md +1319 -77
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md +66 -11
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md +19 -1
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_RECEIPT_VERIFIER_HTTP.md +24 -6
- package/standard-skills/translate-native/integrations/commercial_localization_profile.py +23 -0
- package/standard-skills/translate-native/integrations/website_localization.py +234 -10
- package/standard-skills/translate-native/integrations/website_localization_benchmark.py +39 -3
- package/standard-skills/translate-native/integrations/website_localization_cms.py +512 -10
- package/standard-skills/translate-native/integrations/website_localization_cms_client.py +116 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver.py +101 -11
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_runtime.py +12 -1
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_store.py +186 -24
- package/standard-skills/translate-native/integrations/website_localization_cms_source_client.py +64 -1
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery.py +528 -5
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_auth.py +918 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_auth_runtime.py +609 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_client.py +885 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_http.py +1244 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_runtime.py +220 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_sidecar_adapter.py +331 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_capabilities_http.py +444 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_client.py +673 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch.py +1317 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_client.py +826 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_http.py +1152 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_openapi.py +896 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_runtime.py +621 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_http.py +1180 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_runtime.py +1479 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_http.py +133 -17
- package/standard-skills/translate-native/integrations/website_localization_cms_source_runtime.py +319 -4
- package/standard-skills/translate-native/integrations/website_localization_cms_source_service.py +72 -2
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_http.py +13 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver.py +56 -13
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_openapi.py +335 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_runtime.py +66 -1
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_processing_monitor.py +73 -7
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_receiver_client.py +93 -9
- package/standard-skills/translate-native/integrations/website_localization_evidence_http.py +221 -11
- package/standard-skills/translate-native/integrations/website_localization_health.py +6 -0
- package/standard-skills/translate-native/integrations/website_localization_http_provider.py +1 -1
- package/standard-skills/translate-native/integrations/website_localization_quality_profiles.py +350 -0
- package/standard-skills/translate-native/integrations/website_localization_queue.py +126 -56
- package/standard-skills/translate-native/integrations/website_localization_receipt_verifier_http.py +166 -13
- package/standard-skills/translate-native/integrations/website_localization_release.py +423 -17
- package/standard-skills/translate-native/integrations/website_localization_release_coordinator.py +168 -13
- package/standard-skills/translate-native/integrations/website_localization_runner.py +10 -0
- package/standard-skills/translate-native/integrations/website_localization_worker.py +213 -9
- package/standard-skills/translate-native/provenance.json +2 -2
- package/standard-skills/translate-native/references/commercial-localization.md +96 -17
- package/standard-skills/translate-native/scripts/blun_language_guard.py +3 -1
- package/standard-skills/translate-native/scripts/check_commercial_review.py +69 -9
- package/standard-skills/translate-native/scripts/commercial_localization_profile.py +829 -31
- package/standard-tools/language-guard/VERSION +1 -1
- package/standard-tools/language-guard/blun_language_guard.py +3 -1
- package/standard-tools/language-guard/check_commercial_review.py +69 -9
- package/standard-tools/language-guard/commercial_localization_profile.py +829 -31
- package/standard-tools/language-guard/provenance.json +2 -2
- package/standard-tools/manifest.json +1 -1
- package/worker-host.mjs +215 -82
- package/agent-spine-plugin/scripts/check-install-king.js +0 -37
|
@@ -48,12 +48,24 @@ native-Unicode JSON before signing and are never mutated.
|
|
|
48
48
|
|
|
49
49
|
Successful responses require canonical bounded JSON, an allowed status code,
|
|
50
50
|
the exact response schema, and the originating request, event, and site
|
|
51
|
-
bindings. Capability responses additionally recompute both advertised hashes
|
|
52
|
-
|
|
53
|
-
response schemas, and enabled booleans
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
bindings. Capability responses additionally recompute both advertised hashes,
|
|
52
|
+
verify the exact ordered operation names, methods, paths, request schemas,
|
|
53
|
+
response schemas, and enabled booleans, and compare the complete v5 capability
|
|
54
|
+
shape, commercial profile, 24 locale bindings, and commercial rendering
|
|
55
|
+
registry with the installed canonical contract. Rehashing a substituted
|
|
56
|
+
endpoint or registry is therefore insufficient.
|
|
57
|
+
|
|
58
|
+
Production hosts can also pass constructor-fixed
|
|
59
|
+
`capabilities_sha256` and `commercial_rendering_registry_sha256` deployment
|
|
60
|
+
pins. Each must be a lowercase 64-character SHA-256 digest; malformed
|
|
61
|
+
configuration is rejected before transport. A valid response that does not
|
|
62
|
+
match either configured pin fails after the single HTTP attempt with the
|
|
63
|
+
distinct, non-retryable `capabilities_pin_mismatch` or
|
|
64
|
+
`commercial_rendering_registry_pin_mismatch` code. Rotate a pin only as an
|
|
65
|
+
explicit deployment change after installing and validating the corresponding
|
|
66
|
+
client contract. Stable server failures retain their content-free error code
|
|
67
|
+
and derive retryability from HTTP status; redirects and invalid bindings fail
|
|
68
|
+
closed.
|
|
57
69
|
|
|
58
70
|
### Durable change dispatch
|
|
59
71
|
|
|
@@ -214,6 +226,34 @@ never enter the runtime representation or stable failure codes. A deployment
|
|
|
214
226
|
may therefore choose its own secret manager and supervisor without weakening
|
|
215
227
|
the provider-neutral contract.
|
|
216
228
|
|
|
229
|
+
Set `capability_preflight=True` for a pinned production startup. It is
|
|
230
|
+
mandatory whenever `http_authenticator` exposes the runtime over HTTP. The
|
|
231
|
+
runtime then requires both constructor-fixed client pins described above and performs
|
|
232
|
+
one signed capability request after all in-memory configuration and existing
|
|
233
|
+
path checks, but before creating any database file. Missing pins, a network or
|
|
234
|
+
contract failure, and either pin mismatch leave all three paths absent and
|
|
235
|
+
return only a stable content-free failure code. `capability_binding()` reports
|
|
236
|
+
the two verified public digests or the explicit `not_configured` state. Every
|
|
237
|
+
later runtime transition rechecks that the client still exposes the exact
|
|
238
|
+
verified pair before reading or writing persistent state or making another
|
|
239
|
+
network request. This startup proof is deliberately not a hidden retry or a
|
|
240
|
+
claim that the remote service will remain available indefinitely; supervisors
|
|
241
|
+
must construct a new pinned runtime after an approved contract deployment.
|
|
242
|
+
|
|
243
|
+
Pinned startup also writes an independent canonical binding row into the
|
|
244
|
+
change, removal, and lifecycle databases. Each row binds the database role,
|
|
245
|
+
complete capability digest, commercial rendering-registry digest, and a
|
|
246
|
+
derived binding digest. Existing rows are validated before the service may add
|
|
247
|
+
or alter any queue schema. A restart may reuse only the same exact binding;
|
|
248
|
+
swapped database files and another capability generation block with stable
|
|
249
|
+
content-free errors. An unbound database can be adopted only when every
|
|
250
|
+
existing source queue is empty. This permits a safe first pinned deployment
|
|
251
|
+
without allowing pending legacy work to cross the policy boundary. If a crash
|
|
252
|
+
leaves only part of an otherwise matching empty set unbound, the next startup
|
|
253
|
+
converges the missing binding. `capability_binding()` uses its v2 response to
|
|
254
|
+
report all three verified database roles, and every later state transition
|
|
255
|
+
revalidates the canonical rows before queue access.
|
|
256
|
+
|
|
217
257
|
### Durable terminal notification callback
|
|
218
258
|
|
|
219
259
|
Polling remains sufficient, but a deployment can pass `terminal_notifier` and
|
|
@@ -260,11 +300,13 @@ polling contract and does not create notification state.
|
|
|
260
300
|
For a remote backend, pass an
|
|
261
301
|
`HTTPTerminalNotifierAdapter` from
|
|
262
302
|
`integrations/website_localization_cms_terminal_notification_http.py` as the
|
|
263
|
-
`terminal_notifier`.
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
303
|
+
`terminal_notifier`. Construct it with the exact deployment-approved receiver
|
|
304
|
+
capability SHA-256 as well as its endpoint and authentication callback. It
|
|
305
|
+
sends the canonical notification object itself as the request body to one
|
|
306
|
+
configured HTTPS URL. Loopback HTTP is available only by explicit
|
|
307
|
+
test/development opt-in. Redirects are never followed, and the adapter performs
|
|
308
|
+
exactly one transport attempt; the durable notification outbox alone decides
|
|
309
|
+
whether and when to retry.
|
|
268
310
|
|
|
269
311
|
Each request reserves these exact transport headers:
|
|
270
312
|
|
|
@@ -272,7 +314,8 @@ Each request reserves these exact transport headers:
|
|
|
272
314
|
- `Accept: application/json`;
|
|
273
315
|
- `Idempotency-Key: <notification_id>`;
|
|
274
316
|
- `X-Localization-Terminal-Notification-Id: <notification_id>`;
|
|
275
|
-
- `X-Localization-Terminal-Notification-Sha256: <body_sha256
|
|
317
|
+
- `X-Localization-Terminal-Notification-Sha256: <body_sha256>`;
|
|
318
|
+
- `X-Localization-Capabilities-SHA256: <receiver_capabilities_sha256>`.
|
|
276
319
|
|
|
277
320
|
The host-supplied authentication callback receives a fresh copy of this
|
|
278
321
|
content-free request before any network access:
|
|
@@ -286,7 +329,8 @@ content-free request before any network access:
|
|
|
286
329
|
"notification_id": "terminal-<sha256>",
|
|
287
330
|
"event_id": "cms-event-184",
|
|
288
331
|
"site_id": "public-site",
|
|
289
|
-
"body_sha256": "<sha256 of exact canonical request bytes>"
|
|
332
|
+
"body_sha256": "<sha256 of exact canonical request bytes>",
|
|
333
|
+
"capabilities_sha256": "<receiver_capabilities_sha256>"
|
|
290
334
|
}
|
|
291
335
|
```
|
|
292
336
|
|
|
@@ -300,6 +344,22 @@ failures are retryable by the outbox. Other statuses and malformed or
|
|
|
300
344
|
cross-bound successful responses are permanent protocol failures. Response
|
|
301
345
|
bodies and private exceptions are never copied into durable error state.
|
|
302
346
|
|
|
347
|
+
When terminal-status observation is enabled, the source service derives the
|
|
348
|
+
receiver's exact `expected_capabilities_sha256` from the full terminal receiver
|
|
349
|
+
client. A custom notifier/status-reader pair must instead provide the same
|
|
350
|
+
digest explicitly as `terminal_receiver_capabilities_sha256`; missing or
|
|
351
|
+
conflicting pins block configuration before the processing-monitor schema is
|
|
352
|
+
created. The source service rechecks an exposed client pin before status,
|
|
353
|
+
health, or worker progress, while every returned receiver status must carry the
|
|
354
|
+
same exact capability SHA-256.
|
|
355
|
+
|
|
356
|
+
The terminal-processing monitor stores this expected digest in its v2 metadata
|
|
357
|
+
and returns it in content-free health. Restarts may therefore reuse durable
|
|
358
|
+
monitoring work only under the same receiver contract. An empty v1 monitor is
|
|
359
|
+
upgraded transactionally. A v1 monitor containing unbound work is deliberately
|
|
360
|
+
not assigned a guessed generation and remains fail-closed; operators must
|
|
361
|
+
resolve that legacy work with independently verified deployment evidence.
|
|
362
|
+
|
|
303
363
|
#### Reference terminal-notification receiver
|
|
304
364
|
|
|
305
365
|
`integrations/website_localization_cms_terminal_notification_receiver.py`
|
|
@@ -409,9 +469,9 @@ If the configured join timeout expires, close fails while durable state remains
|
|
|
409
469
|
open; the supervisor must resolve or terminate the stuck callback before trying
|
|
410
470
|
again. Construct the hosted runtime after every process fork.
|
|
411
471
|
|
|
412
|
-
#### Terminal-receiver status, health, readiness, and
|
|
472
|
+
#### Terminal-receiver status, health, readiness, capabilities, and OpenAPI
|
|
413
473
|
|
|
414
|
-
The durable runtime also serves
|
|
474
|
+
The durable runtime also serves five authenticated, content-free control routes
|
|
415
475
|
on the same exact HTTPS origin:
|
|
416
476
|
|
|
417
477
|
| Method | Path | Required scope | Purpose |
|
|
@@ -420,6 +480,7 @@ on the same exact HTTPS origin:
|
|
|
420
480
|
| `GET` | `/v1/localization/terminal-notifications/health` | `terminal-notification-health:read` | Inspect aggregate runtime, worker, and durable inbox health |
|
|
421
481
|
| `GET` | `/v1/localization/terminal-notifications/readiness` | `terminal-notification-readiness:read` | Check the managed worker and verified inbox |
|
|
422
482
|
| `GET` | `/v1/localization/terminal-notifications/capabilities` | `terminal-notification-capabilities:read` | Discover the exact active receiver contract |
|
|
483
|
+
| `GET` | `/v1/localization/terminal-notifications/openapi` | `terminal-notification-openapi:read` | Read the capability-bound OpenAPI 3.1 profile |
|
|
423
484
|
|
|
424
485
|
Status accepts only canonical UTF-8 JSON and requires
|
|
425
486
|
`X-Localization-Terminal-Status-SHA256` to equal the exact body hash:
|
|
@@ -458,19 +519,35 @@ inspection, and the read does not claim, retry, complete, or otherwise mutate
|
|
|
458
519
|
processing state.
|
|
459
520
|
|
|
460
521
|
Discovery is also strictly `GET`, body-free, query-free, and separately scoped.
|
|
461
|
-
Its `blun.cms-terminal-receiver-capabilities-response.
|
|
462
|
-
`blun.cms-terminal-receiver-capabilities.
|
|
522
|
+
Its `blun.cms-terminal-receiver-capabilities-response.v3` envelope contains a
|
|
523
|
+
`blun.cms-terminal-receiver-capabilities.v3` contract and canonical SHA-256.
|
|
463
524
|
The digest covers all active operations, including the runtime's configured
|
|
464
525
|
notification intake path, plus methods, scopes, request and response schemas,
|
|
465
526
|
required fields, success statuses, transport limits, processing states, and
|
|
466
527
|
terminal outcomes. It contains no site, endpoint origin, notification,
|
|
467
528
|
credential, website text, provider response, or private error detail. The
|
|
468
529
|
contract includes the health operation's exact method, path, distinct scope,
|
|
469
|
-
schema, fields, and success status.
|
|
530
|
+
schema, fields, and success status. Every non-discovery operation also names
|
|
531
|
+
the required `X-Localization-Capabilities-SHA256` precondition header; the
|
|
532
|
+
contract semantics require its exact active digest.
|
|
533
|
+
|
|
534
|
+
The separately scoped OpenAPI route returns
|
|
535
|
+
`blun.cms-terminal-receiver-openapi-response.v1`. Its canonical OpenAPI 3.1
|
|
536
|
+
document covers all six receiver operations, including a custom notification
|
|
537
|
+
intake path, and recursively closes the notification, acknowledgement, status,
|
|
538
|
+
health, readiness, capability, and error shapes. It declares the exact required
|
|
539
|
+
idempotency, notification-identity, payload-hash, and status-hash headers. Both
|
|
540
|
+
the envelope and document carry the active capability SHA-256; the envelope
|
|
541
|
+
also carries the canonical document SHA-256. Servers are deliberately omitted
|
|
542
|
+
because the deployment owns the HTTPS origin.
|
|
470
543
|
|
|
471
544
|
The capability request authenticates the exact empty-body hash before the
|
|
472
545
|
contract is built. It never reads the inbox, checks worker readiness, claims a
|
|
473
|
-
lease, or calls a handler.
|
|
546
|
+
lease, or calls a handler. Every other route includes the supplied capability
|
|
547
|
+
digest in its authentication context and then requires it to equal the active
|
|
548
|
+
complete generation. Absence returns content-free `428`; drift returns `412`
|
|
549
|
+
before notification persistence, inbox inspection, worker-state reporting, or
|
|
550
|
+
OpenAPI construction. A custom intake path that collides with any control
|
|
474
551
|
route is rejected before SQLite is created. Missing or altered notification
|
|
475
552
|
schema fields, reused scopes, a request body, content type, query, wrong method,
|
|
476
553
|
or private authenticator failure returns a content-free fail-closed response.
|
|
@@ -486,12 +563,28 @@ provided canonical request context. Do not learn and trust the digest from the
|
|
|
486
563
|
same untrusted connection that it is intended to authenticate.
|
|
487
564
|
|
|
488
565
|
`capabilities()` verifies the response envelope, the canonical digest, every
|
|
489
|
-
schema and limit, all
|
|
490
|
-
configured notification path. `health()`, `readiness()`,
|
|
491
|
-
repeat that live contract verification; a contract change
|
|
492
|
-
operational read until the deployment deliberately
|
|
493
|
-
request is separately authenticated and uses
|
|
494
|
-
attempt with no redirects.
|
|
566
|
+
schema and limit, all six operation definitions, distinct scopes, and the
|
|
567
|
+
configured notification path. `health()`, `readiness()`, `status()`, and
|
|
568
|
+
`openapi()` first repeat that live contract verification; a contract change
|
|
569
|
+
therefore blocks the operational read until the deployment deliberately
|
|
570
|
+
updates its pin. Every HTTP request is separately authenticated and uses
|
|
571
|
+
exactly one bounded transport attempt with no redirects.
|
|
572
|
+
|
|
573
|
+
After discovery, the client reserves and sends
|
|
574
|
+
`X-Localization-Capabilities-SHA256` on every operational request and binds the
|
|
575
|
+
same digest into the host authentication context. The receiver checks it after
|
|
576
|
+
authentication but before durable or operational state access. This prevents a
|
|
577
|
+
generation change from accepting a notification under a contract the caller
|
|
578
|
+
did not verify.
|
|
579
|
+
|
|
580
|
+
`openapi()` then reconstructs the complete origin-free OpenAPI 3.1 document
|
|
581
|
+
from the freshly verified capability object and requires the remote document,
|
|
582
|
+
its canonical SHA-256, and its capability binding to match exactly. Rehashing
|
|
583
|
+
a substituted schema, changing the custom notification path between requests,
|
|
584
|
+
or returning another capability generation cannot produce trusted evidence.
|
|
585
|
+
The transport retains the 16,384-byte request limit while accepting at most
|
|
586
|
+
the receiver contract's advertised 1,000,000-byte response limit. The read
|
|
587
|
+
does not touch the inbox or worker state.
|
|
495
588
|
|
|
496
589
|
`notify()` validates the complete immutable terminal notification before any
|
|
497
590
|
network call, repeats the pinned discovery, and sends the canonical bytes to
|
|
@@ -518,7 +611,7 @@ response between the two requests from passing as current evidence.
|
|
|
518
611
|
Malformed JSON, duplicate keys, unexpected fields, inconsistent counts,
|
|
519
612
|
rehashed semantic contract drift, redirects, and private transport failures
|
|
520
613
|
raise `TerminalReceiverClientBlocked` with only a stable code and retryability.
|
|
521
|
-
The
|
|
614
|
+
The four read methods never claim work, mutate receiver state, process a
|
|
522
615
|
notification, or contain website text. `notify()` performs only the documented
|
|
523
616
|
durable intake operation and returns its content-free acknowledgement.
|
|
524
617
|
|
|
@@ -550,9 +643,10 @@ The exact routes are:
|
|
|
550
643
|
| `GET` | `/v1/localization/source/readiness` | `source-readiness:read` | Verify that the managed worker and durable service can accept work |
|
|
551
644
|
| `GET` | `/v1/localization/source/capabilities` | `source-capabilities:read` | Discover the exact active HTTP contract |
|
|
552
645
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
`blun.cms-source-
|
|
646
|
+
Authenticated startup requires `capability_preflight=True`; omission blocks
|
|
647
|
+
before any database is created. The capabilities route accepts no body or query. Its
|
|
648
|
+
`blun.cms-source-capabilities-response.v2` response contains one
|
|
649
|
+
`blun.cms-source-runtime-capabilities.v2` contract with the exact active
|
|
556
650
|
methods, paths, scopes, principal schemas, request and response schemas,
|
|
557
651
|
required top-level fields, success statuses, retry limits, and transport
|
|
558
652
|
bounds. The nested `sha256` is calculated over the canonical capability object
|
|
@@ -561,10 +655,12 @@ reject unexpected contract drift without receiving website content or reading
|
|
|
561
655
|
the three runtime databases. The route has its own
|
|
562
656
|
`source-capabilities:read` credential, performs no state write, lease, repair,
|
|
563
657
|
or network call, and returns fail-closed if its route metadata is incomplete or
|
|
564
|
-
internally inconsistent.
|
|
658
|
+
internally inconsistent. The response also carries the runtime's separately
|
|
659
|
+
validated `blun.cms-source-capability-binding.v2`: the exact commercial
|
|
660
|
+
capability digest, rendering-registry digest, and three durable database roles.
|
|
565
661
|
|
|
566
662
|
The body-free readiness route uses
|
|
567
|
-
`blun.cms-source-readiness-response.
|
|
663
|
+
`blun.cms-source-readiness-response.v3`. It returns HTTP `200` only while the
|
|
568
664
|
managed worker is running and durable service health is `ok` or `degraded`;
|
|
569
665
|
startup, shutdown, a worker exception, closed state, or blocked durable health
|
|
570
666
|
returns HTTP `503`. Its separate `source-readiness:read` credential receives no
|
|
@@ -575,10 +671,11 @@ driven runtimes retain their explicit `run_once` contract.
|
|
|
575
671
|
Change requests use
|
|
576
672
|
`blun.cms-source-change-enqueue-request.v1`; removal requests use
|
|
577
673
|
`blun.cms-source-removal-enqueue-request.v1`. Both contain the exact downstream
|
|
578
|
-
payload plus an explicit `max_attempts` from 1 through 20. Successful
|
|
674
|
+
payload plus an explicit `max_attempts` from 1 through 20. Successful V3
|
|
579
675
|
responses return HTTP `202` with the canonical request identity, payload
|
|
580
|
-
SHA-256, durable state, attempt count, retry ceiling,
|
|
581
|
-
digest. Replaying identical bytes converges on
|
|
676
|
+
SHA-256, durable state, attempt count, retry ceiling, exact HTTP capability
|
|
677
|
+
digest, and verified runtime binding. Replaying identical bytes converges on
|
|
678
|
+
the same durable item. Reusing
|
|
582
679
|
an identity with different content or policy returns HTTP `409` and does not
|
|
583
680
|
alter stored work.
|
|
584
681
|
|
|
@@ -593,8 +690,8 @@ The status request is exact, query-free JSON and uses
|
|
|
593
690
|
}
|
|
594
691
|
```
|
|
595
692
|
|
|
596
|
-
Its `blun.cms-source-status-response.
|
|
597
|
-
`blun.cms-source-service-status.
|
|
693
|
+
Its `blun.cms-source-status-response.v6` response contains one nested
|
|
694
|
+
`blun.cms-source-service-status.v4` snapshot. It binds the stored
|
|
598
695
|
`website_version`, `source_sequence`, canonical change hash, dispatch state and
|
|
599
696
|
attempts, remote plan and job count, local lifecycle state, remote lifecycle
|
|
600
697
|
status, lifecycle hash, required and approved locales, blocked locale reason
|
|
@@ -605,17 +702,22 @@ write. A caller can therefore distinguish queued work, a pending local
|
|
|
605
702
|
registration, active localization, approval, publication, cancellation, and a
|
|
606
703
|
terminal failure without accidentally advancing the worker.
|
|
607
704
|
|
|
608
|
-
|
|
705
|
+
The status projection additionally exposes only the terminal notification state, its
|
|
609
706
|
content-free identity and hash, bounded attempt counters, and a public error
|
|
610
707
|
code. When the terminal notifier exposes the pinned receiver `status` method,
|
|
611
708
|
the snapshot also reports the independently durable processing observation,
|
|
612
|
-
poll failures, receiver attempts,
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
health
|
|
709
|
+
poll failures, receiver attempts, stable local and receiver error codes, and
|
|
710
|
+
the exact terminal receiver capability SHA-256. Disabled observation uses an
|
|
711
|
+
explicit `null` binding. An intake acknowledgement is never presented as
|
|
712
|
+
completed CMS processing.
|
|
713
|
+
|
|
714
|
+
The corresponding `blun.cms-source-health-response.v6` and nested
|
|
715
|
+
`blun.cms-source-service-health.v4` report notification and processing-observer
|
|
716
|
+
backlog plus component health without revealing website content or callback
|
|
717
|
+
responses. The service-level receiver digest must exactly match the monitor
|
|
718
|
+
component's stored digest. Missing, malformed, substituted, or contradictory
|
|
719
|
+
bindings fail closed through the reference client and every outer lifecycle
|
|
720
|
+
projection.
|
|
619
721
|
|
|
620
722
|
Before parsing JSON or touching SQLite, the application calls the host-supplied
|
|
621
723
|
authenticator with this content-free request:
|
|
@@ -653,9 +755,14 @@ credential, exception, source string, or target string.
|
|
|
653
755
|
|
|
654
756
|
`integrations/website_localization_cms_source_client.py` is the provider-neutral
|
|
655
757
|
client for this complete ingress. Construct `CMSLocalizationSourceHTTPClient`
|
|
656
|
-
with one exact HTTPS origin,
|
|
657
|
-
|
|
658
|
-
|
|
758
|
+
with one exact HTTPS origin, the HTTP contract pin, and the source runtime's
|
|
759
|
+
commercial capability and rendering-registry pins supplied through trusted
|
|
760
|
+
deployment configuration. When terminal observation is enabled, also supply
|
|
761
|
+
the exact receiver generation as
|
|
762
|
+
`expected_terminal_receiver_capabilities_sha256`; leaving it unset pins the
|
|
763
|
+
client to the explicitly disabled `null` state. A callback provides
|
|
764
|
+
authentication headers for the
|
|
765
|
+
canonical request context and receives the method,
|
|
659
766
|
origin, verified path and scope, body SHA-256, and the applicable event, site,
|
|
660
767
|
or request identity; it cannot replace framing, idempotency, or binding headers.
|
|
661
768
|
|
|
@@ -666,14 +773,18 @@ operation definition to match the installed contract and trusted pin, takes
|
|
|
666
773
|
the write path from that fresh result, and performs exactly one request. The
|
|
667
774
|
immutable event, cancellation, or tombstone identity is the idempotency key.
|
|
668
775
|
An accepted response must return the same operation, request and event IDs,
|
|
669
|
-
canonical inner-payload hash, retry ceiling,
|
|
776
|
+
canonical inner-payload hash, retry ceiling, capability digest, and exact
|
|
777
|
+
runtime binding.
|
|
670
778
|
|
|
671
779
|
`status()`, `health()`, and `readiness()` repeat discovery independently and
|
|
672
780
|
then validate every returned field and cross-field invariant. Status is bound
|
|
673
|
-
to the requested event
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
781
|
+
to the requested event, site, and configured terminal receiver generation.
|
|
782
|
+
Health requires the same generation at service and monitor-component level;
|
|
783
|
+
health and readiness accept their documented `200` and `503` states only when
|
|
784
|
+
the HTTP status agrees with the nested state.
|
|
785
|
+
All five operational response schemas carry `capabilities_sha256` and the
|
|
786
|
+
runtime binding. A missing, malformed, substituted, or stale binding blocks
|
|
787
|
+
even when the static HTTP schema still matches its separate contract pin.
|
|
677
788
|
|
|
678
789
|
The adapter owns no retry loop. `CMSSourceClientBlocked` contains only a stable
|
|
679
790
|
content-free code and retryability decision, so the website host may apply its
|
|
@@ -752,6 +863,854 @@ keeps the database connection open; close it only after the worker finishes.
|
|
|
752
863
|
Worker exceptions are reduced to `source_delivery_runtime.worker_blocked`, and
|
|
753
864
|
the failed runtime cannot accept more managed source events.
|
|
754
865
|
|
|
866
|
+
When the source client supplies the verified runtime-capability, commercial
|
|
867
|
+
rendering-registry, and terminal-receiver pins, the durable outbox also creates
|
|
868
|
+
one canonical `source_delivery` binding record. It binds all three generations
|
|
869
|
+
together with the source-delivery contract hash and validates the table shape,
|
|
870
|
+
exact row, and derived digest before every queue operation. A same-generation
|
|
871
|
+
restart resumes pending work. Only an empty unbound database, or an exact empty
|
|
872
|
+
v1 binding whose historical adapter digest can be reconstructed, may be bound
|
|
873
|
+
or migrated automatically. A non-empty legacy queue, changed generation,
|
|
874
|
+
altered metadata, or unpinned reopen of an already bound database blocks before
|
|
875
|
+
queue or network access. The production HMAC website-to-sidecar composition
|
|
876
|
+
binds its separate outer database to the same three verified generations. On
|
|
877
|
+
restart it checks the existing file and canonical binding read-only before any
|
|
878
|
+
capability request. A local schema, file-safety, or generation failure therefore
|
|
879
|
+
makes no network request; a new database or safely migratable empty database
|
|
880
|
+
proceeds to the authenticated downstream preflight before creation or migration.
|
|
881
|
+
|
|
882
|
+
#### Website-source delivery HTTP sidecar
|
|
883
|
+
|
|
884
|
+
`integrations/website_localization_cms_source_delivery_http.py` makes the
|
|
885
|
+
protected website outbox available to CMS and website backends that do not
|
|
886
|
+
embed Python. Pass `http_authenticator` to
|
|
887
|
+
`open_hosted_cms_source_delivery()` and serve the resulting `runtime.http`
|
|
888
|
+
WSGI application behind TLS. Invalid authentication configuration is rejected
|
|
889
|
+
during in-memory preflight before the SQLite file is created. Omitting the
|
|
890
|
+
option preserves the manual Python runtime and leaves `runtime.http` as `None`.
|
|
891
|
+
|
|
892
|
+
The sidecar exposes these independently authorized operations:
|
|
893
|
+
|
|
894
|
+
- `POST /v1/localization/source-delivery/changes`
|
|
895
|
+
- `POST /v1/localization/source-delivery/removals`
|
|
896
|
+
- `POST /v1/localization/source-delivery/status`
|
|
897
|
+
- `POST /v1/localization/source-delivery/source-status`
|
|
898
|
+
- `GET /v1/localization/source-delivery/health`
|
|
899
|
+
- `GET /v1/localization/source-delivery/readiness`
|
|
900
|
+
- `GET /v1/localization/source-delivery/source-health`
|
|
901
|
+
- `GET /v1/localization/source-delivery/source-readiness`
|
|
902
|
+
- `GET /v1/localization/source-delivery/capabilities`
|
|
903
|
+
|
|
904
|
+
The authenticator receives schema
|
|
905
|
+
`blun.cms-source-delivery-sidecar-auth-request.v1` with the exact method, path,
|
|
906
|
+
sorted request headers, and SHA-256 of the received body. It returns a stable
|
|
907
|
+
principal, credential identity and version, and the route's exact scope.
|
|
908
|
+
Change, removal, status, and source-status routes additionally require the
|
|
909
|
+
authorized `site_id`; the sidecar compares it independently with the request
|
|
910
|
+
and the runtime result. An unknown request and one belonging to another
|
|
911
|
+
website both return the same content-free `404` response.
|
|
912
|
+
|
|
913
|
+
Change and removal bodies carry the complete immutable payload plus distinct
|
|
914
|
+
`source_max_attempts` and `delivery_max_attempts` values. The
|
|
915
|
+
`Idempotency-Key` must equal the event, cancellation, or tombstone ID, and
|
|
916
|
+
`X-Localization-Source-Payload-SHA256` must equal the canonical inner-payload
|
|
917
|
+
hash. HTTP `202` is returned only after the exact binding has been persisted.
|
|
918
|
+
The sidecar performs no delivery attempt itself; the managed worker retains
|
|
919
|
+
the single-attempt, durable-backoff, and crash-recovery semantics.
|
|
920
|
+
|
|
921
|
+
Status, lifecycle, health, and readiness operations never return website text.
|
|
922
|
+
The source-status route is gated on an exact durably accepted sidecar row; the
|
|
923
|
+
body-free source-health and source-readiness routes keep downstream queue state
|
|
924
|
+
and processing availability separate from sidecar intake. Every outgoing
|
|
925
|
+
runtime object is checked for its exact field set, types, hashes, state
|
|
926
|
+
invariants, request
|
|
927
|
+
identity, and applicable tenant before serialization. The capability route
|
|
928
|
+
describes all nine schemas, methods, paths, scopes, limits, and safety
|
|
929
|
+
semantics under one canonical SHA-256. That digest is repeated on every
|
|
930
|
+
operational response, and any internal contract drift blocks the complete
|
|
931
|
+
response instead of advertising a rehashed weakened interface. Each of the
|
|
932
|
+
three source-facing reads also carries the separately validated source runtime
|
|
933
|
+
binding without exposing content.
|
|
934
|
+
|
|
935
|
+
#### Contract-pinned source-delivery sidecar client
|
|
936
|
+
|
|
937
|
+
`integrations/website_localization_cms_source_delivery_client.py` is the
|
|
938
|
+
provider-neutral HTTPS reference client for all nine sidecar operations.
|
|
939
|
+
Construct `CMSSourceDeliverySidecarHTTPClient` with one exact HTTPS origin, the
|
|
940
|
+
trusted sidecar capability SHA-256, the separately trusted downstream
|
|
941
|
+
source-service capability SHA-256, and a callback that returns authentication
|
|
942
|
+
headers for the immutable request context. Loopback HTTP is available only
|
|
943
|
+
through the explicit test/development option.
|
|
944
|
+
|
|
945
|
+
Before every operational request the client fetches the live capability
|
|
946
|
+
object, validates its complete canonical form against the installed contract,
|
|
947
|
+
and requires its digest to equal the deployment pin. The subsequent request
|
|
948
|
+
uses only the method, path, schema, and success status from that fresh object.
|
|
949
|
+
The authentication callback receives the origin, method, verified path, scope,
|
|
950
|
+
exact body SHA-256, and applicable site, event, request, and payload identities
|
|
951
|
+
under `blun.cms-source-delivery-sidecar-client-auth-context.v1`.
|
|
952
|
+
It cannot supply `Host`, framing, content type, idempotency, or source-payload
|
|
953
|
+
binding headers.
|
|
954
|
+
|
|
955
|
+
`submit_change()` and `submit_removal()` validate and canonically copy the
|
|
956
|
+
complete source event before discovery. The body carries distinct source and
|
|
957
|
+
delivery retry ceilings, while the reserved payload header hashes only the
|
|
958
|
+
immutable inner event. One call performs one transport attempt and follows no
|
|
959
|
+
redirect. Acceptance requires the exact request, event, tenant, payload,
|
|
960
|
+
retry-policy, sidecar-contract, and downstream-contract bindings.
|
|
961
|
+
|
|
962
|
+
`status()` requires the caller's already known operation, request, event,
|
|
963
|
+
tenant, and payload hash; a response cannot silently substitute another
|
|
964
|
+
durable item. `source_status()` adds the complete validated localization
|
|
965
|
+
lifecycle and source runtime binding only after exact durable source
|
|
966
|
+
acceptance. `health()`, `readiness()`,
|
|
967
|
+
`source_health()`, and `source_readiness()` accept HTTP `503` only as an exactly
|
|
968
|
+
validated blocked snapshot. Transport and server failures expose stable
|
|
969
|
+
content-free codes plus retryability, but the client never schedules a retry.
|
|
970
|
+
|
|
971
|
+
For the authenticated production path, construct
|
|
972
|
+
`RotatingHMACCMSSourceDeliveryClient` from
|
|
973
|
+
`website_localization_cms_source_delivery_auth_runtime.py`. Supply the exact
|
|
974
|
+
origin, sidecar capability SHA-256, downstream capability SHA-256, initial
|
|
975
|
+
`HMACCredential`, clock/nonce policy, timeout, and optional transport once. The
|
|
976
|
+
composition creates one private `RotatingSourceDeliveryHMACSigner` and one
|
|
977
|
+
`CMSSourceDeliverySidecarHTTPClient` from that same immutable configuration.
|
|
978
|
+
Invalid construction is reduced to
|
|
979
|
+
`source_delivery_hmac.client_configuration_invalid` before any network call.
|
|
980
|
+
|
|
981
|
+
The composed surface exposes `capabilities()`, `submit_change()`,
|
|
982
|
+
`submit_removal()`, `status()`, `source_status()`, `health()`, `readiness()`,
|
|
983
|
+
`source_health()`, and `source_readiness()` with the original contract
|
|
984
|
+
signatures. `replace_credential()` updates the exact signer used by all nine
|
|
985
|
+
routes. The client is process-bound before delegation, so a forked worker
|
|
986
|
+
cannot reach its inherited transport; create a fresh client in the child from
|
|
987
|
+
host-owned secret state. Client errors retain the underlying stable
|
|
988
|
+
content-free retry decision,
|
|
989
|
+
and neither the wrapper nor its representation exposes the credential, tenant,
|
|
990
|
+
endpoint, or website content.
|
|
991
|
+
|
|
992
|
+
#### Owned authenticated website submission runtime
|
|
993
|
+
|
|
994
|
+
`integrations/website_localization_cms_source_delivery_submission_runtime.py`
|
|
995
|
+
is the production composition root for a website process that submits through
|
|
996
|
+
the authenticated sidecar. Use
|
|
997
|
+
`open_durable_hmac_cms_source_delivery_submission()` for an externally driven
|
|
998
|
+
loop or `open_hosted_hmac_cms_source_delivery_submission()` to start the owned
|
|
999
|
+
non-daemon worker. Both construct one `RotatingHMACCMSSourceDeliveryClient`,
|
|
1000
|
+
one `CMSSourceDeliverySidecarOutboxAdapter`, and one guarded SQLite runtime.
|
|
1001
|
+
|
|
1002
|
+
Supply the initial `HMACCredential`, exact HTTPS origin, trusted sidecar and
|
|
1003
|
+
downstream capability hashes, the expected source-runtime capability SHA-256,
|
|
1004
|
+
the expected commercial rendering-registry SHA-256, the expected terminal-
|
|
1005
|
+
receiver capability SHA-256, worker identity, and the middle
|
|
1006
|
+
`sidecar_delivery_max_attempts` once. Before opening the website SQLite file,
|
|
1007
|
+
the composition reads source readiness through the authenticated sidecar and
|
|
1008
|
+
requires its verified capability binding to match all three generation pins.
|
|
1009
|
+
Unavailable, missing, partial, malformed, or substituted evidence blocks with
|
|
1010
|
+
a stable content-free error before database creation. The hosted factory still
|
|
1011
|
+
validates all loop delays before that preflight.
|
|
1012
|
+
|
|
1013
|
+
All three verified generation values become part of the v3 adapter capability
|
|
1014
|
+
digest and the outer outbox's v2 role-specific durable binding. A restart
|
|
1015
|
+
therefore resumes pending website work only under the exact same sidecar
|
|
1016
|
+
adapter, source-runtime, commercial-rendering, and terminal-receiver
|
|
1017
|
+
generation. The SQLite file retains the existing owner-only, process-bound,
|
|
1018
|
+
inode-guarded lifecycle. Only an exact empty v1 binding can migrate, using the
|
|
1019
|
+
reconstructed v2 adapter digest; existing legacy work is never relabelled.
|
|
1020
|
+
|
|
1021
|
+
Call `submission_capabilities()` to discover the exact live contract of this
|
|
1022
|
+
complete website edge. The content-free
|
|
1023
|
+
`blun.cms-source-delivery-submission-capabilities.v7` snapshot advertises the
|
|
1024
|
+
public change, removal, acceptance-status, and lifecycle HTTPS contracts, all
|
|
1025
|
+
six composed operational
|
|
1026
|
+
projection schemas, the separately owned website, sidecar and source retry
|
|
1027
|
+
budgets, and the explicit rule that durable website-outbox acceptance is not
|
|
1028
|
+
source acceptance or publication. It also
|
|
1029
|
+
states that this edge neither generates translations nor grants publication
|
|
1030
|
+
authority. Its
|
|
1031
|
+
canonical SHA-256 binds the locally verified website generation to the current
|
|
1032
|
+
sidecar and source-service capability pins.
|
|
1033
|
+
|
|
1034
|
+
The method validates the guarded SQLite generation before it performs one
|
|
1035
|
+
fresh authenticated sidecar capability request. A missing or changed local
|
|
1036
|
+
binding therefore causes no network traffic. A stale, substituted or malformed
|
|
1037
|
+
sidecar contract blocks the whole snapshot; the runtime never returns partial
|
|
1038
|
+
capabilities. Returned nested maps are defensive copies and contain no
|
|
1039
|
+
endpoint, credential, tenant, source text, target text or project price.
|
|
1040
|
+
|
|
1041
|
+
For a separately hosted website process, wrap that same runtime with
|
|
1042
|
+
`build_submission_http()` from
|
|
1043
|
+
`integrations/website_localization_cms_source_delivery_submission_http.py`.
|
|
1044
|
+
It exposes the capability route plus two durable write routes:
|
|
1045
|
+
|
|
1046
|
+
| Method | Path | Required scope |
|
|
1047
|
+
| --- | --- | --- |
|
|
1048
|
+
| `GET` | `/v1/localization/source-delivery/submission-capabilities` | `source-delivery-submission-capabilities:read` |
|
|
1049
|
+
| `POST` | `/v1/localization/source-delivery/submissions/changes` | `source-delivery-submission-change:write` |
|
|
1050
|
+
| `POST` | `/v1/localization/source-delivery/submissions/removals` | `source-delivery-submission-removal:write` |
|
|
1051
|
+
| `POST` | `/v1/localization/source-delivery/submissions/status` | `source-delivery-submission-status:read` |
|
|
1052
|
+
| `POST` | `/v1/localization/source-delivery/submissions/lifecycle` | `source-delivery-submission-lifecycle:read` |
|
|
1053
|
+
| `GET` | `/v1/localization/source-delivery/submissions/pipeline-health` | `source-delivery-submission-pipeline-health:read` |
|
|
1054
|
+
| `GET` | `/v1/localization/source-delivery/submissions/pipeline-readiness` | `source-delivery-submission-pipeline-readiness:read` |
|
|
1055
|
+
|
|
1056
|
+
The two operator routes require an exact body-free HTTPS GET and a site-free
|
|
1057
|
+
operator principal. Their scopes are intentionally distinct. They expose only
|
|
1058
|
+
the already content-free composed runtime projections, after independently
|
|
1059
|
+
revalidating every nested component, capability hash, and runtime binding.
|
|
1060
|
+
Health preserves `ok`, `degraded`, and `blocked`; readiness preserves only
|
|
1061
|
+
whether every required worker can accept and process work. Neither route
|
|
1062
|
+
accepts a query, identifies a tenant, returns source or target text, or grants
|
|
1063
|
+
quality approval or publication authority.
|
|
1064
|
+
|
|
1065
|
+
The capability-discovery route still requires HTTPS, no query, no request body, no content
|
|
1066
|
+
type, and no transfer encoding. Before any local database read or sidecar
|
|
1067
|
+
request, the adapter calls the deployment-owned authenticator with schema
|
|
1068
|
+
`blun.cms-source-delivery-submission-capabilities-auth-request.v1`, the exact
|
|
1069
|
+
method and path, normalized request headers, and the SHA-256 of the empty body.
|
|
1070
|
+
The authenticator must return only principal schema
|
|
1071
|
+
`blun.cms-source-delivery-submission-capabilities-principal.v1`, principal ID,
|
|
1072
|
+
credential ID and version, and the exact required scope. Deployments may use
|
|
1073
|
+
HMAC, mutual TLS, a bearer-token proxy, or another verifier; replay prevention,
|
|
1074
|
+
credential storage, and rotation remain host responsibilities.
|
|
1075
|
+
|
|
1076
|
+
Each write route requires HTTPS, canonical UTF-8 JSON, an exact decimal
|
|
1077
|
+
`Content-Length`, no query or transfer encoding, and a body of at most
|
|
1078
|
+
4,000,000 bytes. Its envelope contains exactly one change or removal plus the
|
|
1079
|
+
independent `source_max_attempts` and `delivery_max_attempts` values, each from
|
|
1080
|
+
1 through 20. `Idempotency-Key` must equal the event, cancellation, or
|
|
1081
|
+
tombstone identity. `X-Localization-Source-Payload-Sha256` must equal the
|
|
1082
|
+
canonical SHA-256 of the nested source payload. Duplicate JSON keys,
|
|
1083
|
+
non-finite numbers, a UTF-8 BOM, wrong payload type, wrong identifier, wrong
|
|
1084
|
+
hash, or a different retry budget on replay blocks before persistence.
|
|
1085
|
+
|
|
1086
|
+
The write authenticator receives only normalized request metadata and the
|
|
1087
|
+
whole-body SHA-256 under
|
|
1088
|
+
`blun.cms-source-delivery-submission-http-auth-request.v1`. It must return the
|
|
1089
|
+
exact write scope and an authorized `site_id` under
|
|
1090
|
+
`blun.cms-source-delivery-submission-write-principal.v1`. A foreign site is
|
|
1091
|
+
reported as not found and cannot reach readiness, generation, or queue state.
|
|
1092
|
+
The hosted worker and role-specific commercial capability generation must both
|
|
1093
|
+
be ready before enqueue. Only after SQLite commits the immutable outer-outbox
|
|
1094
|
+
row does the adapter return HTTP 202 with content-free identity, hashes,
|
|
1095
|
+
separate retry ceilings, current local queue status, and the verified website
|
|
1096
|
+
generation. That acknowledgement never means sidecar or source acceptance,
|
|
1097
|
+
quality approval, translation generation, or publication. An exact replay is
|
|
1098
|
+
safe; an identity collision returns a content-free conflict.
|
|
1099
|
+
|
|
1100
|
+
The two operational read routes require HTTPS and an exact UTF-8 JSON envelope
|
|
1101
|
+
containing only schema, operation, request ID, event ID, site ID, and the
|
|
1102
|
+
canonical source-payload SHA-256. They use the distinct authentication schema
|
|
1103
|
+
`blun.cms-source-delivery-submission-read-auth-request.v1`; the authenticator
|
|
1104
|
+
must return the route-specific read scope and authorized site under
|
|
1105
|
+
`blun.cms-source-delivery-submission-read-principal.v1`. Foreign sites return
|
|
1106
|
+
the same not-found boundary as absent work before any runtime lookup.
|
|
1107
|
+
|
|
1108
|
+
The status route returns the independently validated website and sidecar
|
|
1109
|
+
acceptance projection. The lifecycle route retains that projection as a
|
|
1110
|
+
nested object and, only after source acceptance, adds the validated source
|
|
1111
|
+
processing lifecycle and its separate capability binding. Exact request
|
|
1112
|
+
identity, retry limits, source and website bindings, counters, and nested site
|
|
1113
|
+
identity are rechecked before serialization. Neither HTTP 200 nor an
|
|
1114
|
+
`accepted` state implies linguistic approval or publication; malformed,
|
|
1115
|
+
cross-bound, or unavailable state returns only a content-free blocking error.
|
|
1116
|
+
|
|
1117
|
+
Deployments that need read-only discovery may continue to use
|
|
1118
|
+
`build_submission_capabilities_http()` directly. Both builders validate the
|
|
1119
|
+
same v5 capability snapshot, so the advertised public routes cannot drift from
|
|
1120
|
+
the hosted write boundary.
|
|
1121
|
+
|
|
1122
|
+
Python and separately deployed website backends may consume the complete
|
|
1123
|
+
edge through `CMSSourceDeliverySubmissionHTTPClient` in
|
|
1124
|
+
`integrations/website_localization_cms_source_delivery_submission_client.py`.
|
|
1125
|
+
Construct it with one exact HTTPS origin, the deployment-approved complete
|
|
1126
|
+
submission-capability SHA-256, and a host-owned authentication-header callback.
|
|
1127
|
+
The callback receives schema
|
|
1128
|
+
`blun.cms-source-delivery-submission-client-auth-context.v1`, exact method,
|
|
1129
|
+
origin, freshly discovered path and scope, canonical body SHA-256, and—where
|
|
1130
|
+
applicable—the site, event, request, and source-payload identities. Credentials
|
|
1131
|
+
remain outside the adapter.
|
|
1132
|
+
|
|
1133
|
+
`submit_change()` and `submit_removal()` validate one complete source payload
|
|
1134
|
+
before discovery, use only the freshly advertised write contract, and add the
|
|
1135
|
+
reserved idempotency and source-payload digest headers after authentication.
|
|
1136
|
+
`submission_status()` and `submission_lifecycle()` require the caller's full
|
|
1137
|
+
known operation, request, event, site, and payload-hash binding; they do not
|
|
1138
|
+
offer identifier-only enumeration. `pipeline_health()` and
|
|
1139
|
+
`pipeline_readiness()` are distinct, body-free, site-free operator operations.
|
|
1140
|
+
|
|
1141
|
+
Every method first validates the exact complete v5 capability shape, canonical
|
|
1142
|
+
digest, durable website binding, and sidecar/source generation hashes against
|
|
1143
|
+
the configured deployment pin. It then performs exactly one operational
|
|
1144
|
+
transport attempt and independently validates the entire response against the
|
|
1145
|
+
request and that same discovered generation. Authentication headers may not
|
|
1146
|
+
replace `Host`, framing, media-type, idempotency, or payload-binding headers.
|
|
1147
|
+
The default transport follows no redirects and performs no retry; a caller may
|
|
1148
|
+
schedule a bounded retry only when the stable content-free failure explicitly
|
|
1149
|
+
reports `retryable: true`, and must replay the identical immutable request.
|
|
1150
|
+
Representations and failures expose no origin, credential, tenant, source, or
|
|
1151
|
+
target text.
|
|
1152
|
+
|
|
1153
|
+
#### Durable caller-side public submission
|
|
1154
|
+
|
|
1155
|
+
`integrations/website_localization_cms_source_delivery_submission_dispatch.py`
|
|
1156
|
+
adds the crash-safe caller-owned handoff for that one-attempt client. Construct
|
|
1157
|
+
`DurableCMSSourceDeliverySubmissionDispatcher` over a dedicated SQLite
|
|
1158
|
+
connection and the same deployment-approved complete capability SHA-256 as the
|
|
1159
|
+
client. The database metadata permanently binds queued work to that generation;
|
|
1160
|
+
a restart with another pin blocks before a claim or network call.
|
|
1161
|
+
|
|
1162
|
+
`enqueue()` accepts one complete change, cancellation, or tombstone and commits
|
|
1163
|
+
its canonical payload plus operation, request, event, site, payload hash, and
|
|
1164
|
+
all three retry ceilings before transport. `client_max_attempts` belongs only
|
|
1165
|
+
to the CMS-to-website hop. `delivery_max_attempts` remains the website-to-
|
|
1166
|
+
sidecar ceiling, and `source_max_attempts` remains the source-processing
|
|
1167
|
+
ceiling. An exact enqueue is idempotent; changed content or any changed retry
|
|
1168
|
+
budget under the same identity is a collision.
|
|
1169
|
+
|
|
1170
|
+
`run_once()` validates the dispatcher's schema and the client's immutable pin,
|
|
1171
|
+
then claims at most one due row with a random token. It calls exactly one client
|
|
1172
|
+
method, prioritizing due cancellations and tombstones over equally old changes,
|
|
1173
|
+
and schedules exponential backoff only for a failure whose client
|
|
1174
|
+
contract explicitly marks it retryable. A permanent failure or exhausted local
|
|
1175
|
+
ceiling stays failed. If the process stops after remote HTTP 202 but before the
|
|
1176
|
+
local completion commit, lease expiry makes the next worker replay the exact
|
|
1177
|
+
stored request; the website edge's idempotency remains authoritative.
|
|
1178
|
+
|
|
1179
|
+
`status()` and `health()` expose content-free identities, counters, stable
|
|
1180
|
+
failure codes, capability hashes, and response hashes. They never expose the
|
|
1181
|
+
stored payload. Once—and only once—a record is locally `accepted`, `status()`
|
|
1182
|
+
also returns the complete verified website capability binding from the
|
|
1183
|
+
canonical stored intake response. This identifies the exact delivery, runtime,
|
|
1184
|
+
commercial-rendering registry, and terminal-receiver generations without
|
|
1185
|
+
revealing website content. The binding's own hash and delivery capability pin
|
|
1186
|
+
are rechecked at every projection. Every read revalidates the complete row;
|
|
1187
|
+
altered source text, hashes, retry limits, leases, response evidence, schema,
|
|
1188
|
+
or generation metadata block fail-closed. Local `accepted` records only durable
|
|
1189
|
+
website intake and do not mean source acceptance, quality approval,
|
|
1190
|
+
translation completion, or publication readiness.
|
|
1191
|
+
|
|
1192
|
+
#### Owned public-submission runtime
|
|
1193
|
+
|
|
1194
|
+
`integrations/website_localization_cms_source_delivery_submission_dispatch_runtime.py`
|
|
1195
|
+
is the production composition root for that caller-side outbox. Use
|
|
1196
|
+
`open_durable_cms_source_delivery_submission_dispatch()` for an externally
|
|
1197
|
+
scheduled worker, or `open_hosted_cms_source_delivery_submission_dispatch()`
|
|
1198
|
+
to own one supervised non-daemon worker. Both factories validate the complete
|
|
1199
|
+
client pin, retry and lease policy, clock, worker identity, and—on restart—the
|
|
1200
|
+
exact stored schema and every durable row before operational schema mutation.
|
|
1201
|
+
|
|
1202
|
+
For file-backed operation, pass a normalized absolute path below an owner-held
|
|
1203
|
+
safe directory. The runtime creates the SQLite file with mode `0600`, binds its
|
|
1204
|
+
device and inode, rejects links and replacements, checks the current process
|
|
1205
|
+
before acquiring locks, and serializes all connection access. It rechecks the
|
|
1206
|
+
file, parent directories, and client capability pin around every enqueue,
|
|
1207
|
+
status, health, or delivery transition. A stale or malformed generation is
|
|
1208
|
+
therefore rejected locally before the public HTTPS client can make a request.
|
|
1209
|
+
|
|
1210
|
+
Hosted intake is gated on a live supervised worker. `worker_readiness()` is a
|
|
1211
|
+
content-free snapshot containing only worker state, outbox state, a stable
|
|
1212
|
+
error code, and the pinned capability digest; it grants no publication
|
|
1213
|
+
authority. `close()` first signals and joins the worker. If a transport call
|
|
1214
|
+
does not return within the configured bound, shutdown fails closed and leaves
|
|
1215
|
+
SQLite open so the caller can recover deliberately instead of closing storage
|
|
1216
|
+
beneath an active attempt.
|
|
1217
|
+
|
|
1218
|
+
#### Authenticated CMS submission sidecar
|
|
1219
|
+
|
|
1220
|
+
`integrations/website_localization_cms_source_delivery_submission_dispatch_http.py`
|
|
1221
|
+
wraps the owned runtime in a strict HTTPS/WSGI contract for non-Python CMS and
|
|
1222
|
+
website backends. Pass a callable `http_authenticator` to either runtime
|
|
1223
|
+
factory; the resulting application is available as `runtime.http`. A hosted
|
|
1224
|
+
runtime is required for public writes. An externally scheduled, unmanaged, or
|
|
1225
|
+
stopped worker remains observable but rejects enqueue before request parsing or
|
|
1226
|
+
outbox access.
|
|
1227
|
+
|
|
1228
|
+
The canonical capability response at
|
|
1229
|
+
`GET /v1/localization/cms-submission-dispatch/capabilities` publishes the exact
|
|
1230
|
+
method, path, scope, principal schema, request schema, response schema, limits,
|
|
1231
|
+
retry ownership, non-publication semantics, and downstream public-submission
|
|
1232
|
+
capability pin. The complete object has its own canonical SHA-256. Health and
|
|
1233
|
+
readiness use separate body-free operator scopes. Health describes durable
|
|
1234
|
+
outbox integrity; readiness additionally requires the supervised worker to be
|
|
1235
|
+
alive and the outbox to be healthy.
|
|
1236
|
+
|
|
1237
|
+
Queue and status responses share a closed status shape. A pending, leased,
|
|
1238
|
+
retrying, or failed row has a null `remote_website_capability_binding`; an
|
|
1239
|
+
accepted row must contain the exact complete binding and matching
|
|
1240
|
+
`remote_binding_sha256` and `remote_capabilities_sha256` values. The HTTP
|
|
1241
|
+
server and reference client independently enforce this invariant, so a stale,
|
|
1242
|
+
partial, or substituted generation is not treated as a valid status.
|
|
1243
|
+
|
|
1244
|
+
`GET /v1/localization/cms-submission-dispatch/openapi` uses its own body-free
|
|
1245
|
+
operator scope and returns an origin-free OpenAPI 3.1 document generated from
|
|
1246
|
+
that exact capability object. It describes all eight routes with their methods,
|
|
1247
|
+
scopes, principal schemas, request and response schemas, required idempotency
|
|
1248
|
+
and payload-hash headers, transport limits, retry ownership, and fail-closed
|
|
1249
|
+
publication semantics. The response binds the canonical document hash to the
|
|
1250
|
+
active capability hash and contains no server URL, tenant identity, website
|
|
1251
|
+
content, model provider, or credential value.
|
|
1252
|
+
|
|
1253
|
+
The enqueue payload is a closed discriminated union keyed by `schema` for
|
|
1254
|
+
`blun.cms-content-change.v2`, `blun.cms-content-cancellation.v1`, and
|
|
1255
|
+
`blun.cms-content-tombstone.v1`. Changes carry the complete closed localization
|
|
1256
|
+
request, including NFC source text, canonical BCP-47 source locale, content
|
|
1257
|
+
type, glossary/policy/model/software versions, and an optional unique target
|
|
1258
|
+
array restricted to the 24 exact EU locale profiles. Cancellation and
|
|
1259
|
+
tombstone shapes contain only their immutable request and source identities.
|
|
1260
|
+
The v3 capability document binds all three payload schema IDs. JSON Schema
|
|
1261
|
+
metadata records the UTF-8 source byte ceiling and source-language exclusion;
|
|
1262
|
+
the runtime remains authoritative for checks JSON Schema cannot express
|
|
1263
|
+
portably, including NFC bytes, canonical locale casing, and language-family
|
|
1264
|
+
exclusion.
|
|
1265
|
+
|
|
1266
|
+
The capability response is also fully machine-readable rather than an open
|
|
1267
|
+
placeholder. Its OpenAPI component recursively closes every nested object and
|
|
1268
|
+
fixes each route, method, scope, principal, request and response schema, limit,
|
|
1269
|
+
retry owner, source-event schema, downstream capability pin, and fail-closed
|
|
1270
|
+
semantic to the active generation. The v4 capability document additionally
|
|
1271
|
+
binds `openapi_document_schema`; therefore an older or replaced description
|
|
1272
|
+
cannot keep the same capability SHA-256 even if its routes appear compatible.
|
|
1273
|
+
|
|
1274
|
+
The v5 capability generation additionally publishes the exact ordered
|
|
1275
|
+
`error_statuses` for every operation. The v4 OpenAPI document renders those as
|
|
1276
|
+
concrete responses and has no catch-all `default` response. Enqueue exposes
|
|
1277
|
+
conflict and body-framing outcomes, status exposes its tenant-safe not-found
|
|
1278
|
+
outcome, and all routes expose their authentication and availability failures.
|
|
1279
|
+
For health and readiness only, `503` is a `oneOf` between the route's normal
|
|
1280
|
+
content-free monitor envelope and the standard fail-closed error envelope;
|
|
1281
|
+
this matches the runtime distinction between a valid degraded state and an
|
|
1282
|
+
inability to produce trustworthy monitoring evidence.
|
|
1283
|
+
|
|
1284
|
+
The v6 capability generation and v5 OpenAPI document also bind semantic
|
|
1285
|
+
response invariants. `SubmissionStatus` uses JSON Schema 2020-12 conditionals
|
|
1286
|
+
to require a lease expiry exactly for `leased`, and complete remote status,
|
|
1287
|
+
attempt and digest evidence exactly for `accepted`. Health permits `ok` only
|
|
1288
|
+
with zero failures and expired leases, while `blocked` requires at least one
|
|
1289
|
+
of those signals. Readiness is a closed union between a running, healthy,
|
|
1290
|
+
error-free `ready` state and a `not_ready` state with a stable error code.
|
|
1291
|
+
Each operation carries the same ordered `x-response-invariants` list as its
|
|
1292
|
+
capability record. Stable identifiers retain rules that portable JSON Schema
|
|
1293
|
+
cannot encode, including attempt-count comparisons, request-identity equality
|
|
1294
|
+
and queue-count sums; runtime and the pinned reference client remain
|
|
1295
|
+
authoritative for those relationships.
|
|
1296
|
+
|
|
1297
|
+
The v7 capability generation and v6 OpenAPI document bind every fail-closed
|
|
1298
|
+
error code to its exact route and HTTP status. Each concrete non-success
|
|
1299
|
+
response carries a closed `x-error-codes` list and an identical schema enum;
|
|
1300
|
+
the complete per-operation map is part of the capability SHA-256. Bodyless
|
|
1301
|
+
discovery and monitor routes include `411` for an invalid declared length and
|
|
1302
|
+
`413` for an oversized body, matching the shared framing parser rather than an
|
|
1303
|
+
idealized GET-only path.
|
|
1304
|
+
|
|
1305
|
+
The reference client validates a remote error as a three-field closed envelope
|
|
1306
|
+
before exposing `http_status` and `remote_error_code` on its content-free
|
|
1307
|
+
exception. Codes outside the pinned status-specific set, extra fields,
|
|
1308
|
+
mismatched schemas, malformed JSON, and undeclared statuses never become
|
|
1309
|
+
trusted reasons. Verified `503` errors remain retryable and a verified `409`
|
|
1310
|
+
idempotency collision remains terminal; the exception message itself contains
|
|
1311
|
+
only the stable local failure code.
|
|
1312
|
+
|
|
1313
|
+
The v8 capability generation and v7 OpenAPI document additionally require
|
|
1314
|
+
`X-Localization-Capabilities-SHA256` on every route except authenticated
|
|
1315
|
+
capability discovery. The header must equal the complete active sidecar
|
|
1316
|
+
capability SHA-256 and participates in the host authentication context. A
|
|
1317
|
+
missing header returns the advertised content-free `428`; a stale or replaced
|
|
1318
|
+
generation returns `412`. Both failures occur before enqueue, status lookup,
|
|
1319
|
+
health/readiness access, or OpenAPI generation, so a capability change between
|
|
1320
|
+
discovery and operation cannot persist or expose work under an unexpected
|
|
1321
|
+
contract. Discovery itself remains the bootstrap and therefore requires no
|
|
1322
|
+
self-referential precondition.
|
|
1323
|
+
|
|
1324
|
+
The v12 capability generation and v11 OpenAPI document bind commercial-profile
|
|
1325
|
+
discovery to the actual enqueue operation. Every enqueue request includes
|
|
1326
|
+
`commercial_contract_binding`. For a `commercial` change it must exactly match
|
|
1327
|
+
the active profile identifier, profile SHA-256, and complete 24-locale
|
|
1328
|
+
rendering-registry SHA-256 advertised by the same capability generation. For
|
|
1329
|
+
all other content types, cancellations, and tombstones it must be `null`.
|
|
1330
|
+
|
|
1331
|
+
The binding is part of the body authenticated before JSON parsing. The runtime
|
|
1332
|
+
then compares it with the freshly reconstructed capability before durable
|
|
1333
|
+
enqueue. The OpenAPI schema expresses the same content-type conditional, and
|
|
1334
|
+
the reference client derives the value only from its independently pinned
|
|
1335
|
+
capability. The binding is content-free and carries no price, currency, tax,
|
|
1336
|
+
term, brand, product, source text, target text, credential, or publication
|
|
1337
|
+
authority.
|
|
1338
|
+
|
|
1339
|
+
The v13 capability generation and v12 OpenAPI document make that
|
|
1340
|
+
acknowledgement durable. The caller-owned outbox stores its canonical closed
|
|
1341
|
+
binding beside the immutable payload hash and returns it through queue, status,
|
|
1342
|
+
and lifecycle state. Claims and retries carry the same value, and every row is
|
|
1343
|
+
revalidated against both its source payload and the installed commercial
|
|
1344
|
+
profile before a network call or status response. Cancellation, tombstone, and
|
|
1345
|
+
non-commercial rows retain an exact `null` binding.
|
|
1346
|
+
|
|
1347
|
+
Schema v2 migrates only an exact, empty schema-v1 outbox under a transaction.
|
|
1348
|
+
A populated legacy outbox remains byte-for-byte untouched and blocks startup:
|
|
1349
|
+
the service cannot truthfully infer which historic commercial contract its
|
|
1350
|
+
rows acknowledged. Missing, modified, non-canonical, stale, or cross-content
|
|
1351
|
+
bindings likewise block fail-closed rather than being repaired automatically.
|
|
1352
|
+
|
|
1353
|
+
The v14 capability generation and v13 OpenAPI document bind that durable CMS
|
|
1354
|
+
acknowledgement to the website generation that actually accepts the work. For
|
|
1355
|
+
an accepted commercial change, the downstream
|
|
1356
|
+
`commercial_rendering_registry_sha256` must equal the same field in the stored
|
|
1357
|
+
`commercial_contract_binding`. A different website binding is rejected even
|
|
1358
|
+
when all of its fields and its own `binding_sha256` are internally consistent.
|
|
1359
|
+
|
|
1360
|
+
This cross-generation invariant is checked before the acceptance transaction,
|
|
1361
|
+
again whenever the stored row is read after a restart or by health, and once
|
|
1362
|
+
more at both the HTTP serialization boundary and the reference client. The
|
|
1363
|
+
status and lifecycle remain content-free and grant no publication authority;
|
|
1364
|
+
an unresolved generation mismatch cannot be reported as accepted.
|
|
1365
|
+
|
|
1366
|
+
The v11 capability generation and v10 OpenAPI document add
|
|
1367
|
+
`GET /v1/localization/cms-submission-dispatch/commercial-profile` with a
|
|
1368
|
+
separate body-free operator scope. It returns the exact public
|
|
1369
|
+
`translate-native.commercial.v13` profile, its ten ordered preservation and
|
|
1370
|
+
review dimensions, and the complete 24-locale rendering registry. The payload
|
|
1371
|
+
contains only policy, version, authority, locale, Unicode rendering, and hash
|
|
1372
|
+
data; project prices, brands, products, credentials, source text, and target
|
|
1373
|
+
text are excluded by the closed contract. It is explicitly content-free and
|
|
1374
|
+
grants no publication authority.
|
|
1375
|
+
|
|
1376
|
+
Before producing that response, the dispatcher fetches and revalidates the
|
|
1377
|
+
live downstream website capability generation. The website binding's
|
|
1378
|
+
commercial-rendering SHA-256 must equal the canonical registry returned by the
|
|
1379
|
+
route. Missing capability preconditions, stale website generations, registry
|
|
1380
|
+
drift, malformed locale sets, or substituted profile fields block before any
|
|
1381
|
+
response is serialized.
|
|
1382
|
+
|
|
1383
|
+
`POST /v1/localization/cms-submission-dispatch/requests` authenticates the
|
|
1384
|
+
method, path, headers, and exact raw-body SHA-256 before decoding JSON. Its
|
|
1385
|
+
tenant principal must match the payload's `site_id`; `Idempotency-Key` must
|
|
1386
|
+
match the immutable request identity; and
|
|
1387
|
+
`X-Localization-Source-Payload-SHA256` must match the canonical complete source
|
|
1388
|
+
payload. The request carries distinct `client_max_attempts`,
|
|
1389
|
+
`delivery_max_attempts`, and `source_max_attempts` values. HTTP 202 follows only
|
|
1390
|
+
after the local durable commit and explicitly means website intake only—not
|
|
1391
|
+
source acceptance, linguistic approval, or publication.
|
|
1392
|
+
|
|
1393
|
+
`POST /v1/localization/cms-submission-dispatch/status` uses a distinct tenant
|
|
1394
|
+
read scope and requires the complete known operation, request, event, site, and
|
|
1395
|
+
payload-hash identity. A foreign tenant, altered identity, and absent request
|
|
1396
|
+
all produce the same content-free not-found response. Every operational result
|
|
1397
|
+
is independently revalidated against the active capability generation before
|
|
1398
|
+
serialization. Invalid framing, authentication outage, capability or storage
|
|
1399
|
+
drift, a malformed runtime result, and a dead worker therefore block without
|
|
1400
|
+
returning stored source content or invoking the downstream public client.
|
|
1401
|
+
|
|
1402
|
+
`POST /v1/localization/cms-submission-dispatch/lifecycle` extends that exact
|
|
1403
|
+
tenant identity into the downstream source lifecycle. It is available only
|
|
1404
|
+
after the caller-owned outbox has durably recorded website acceptance; every
|
|
1405
|
+
earlier outer state returns the advertised non-retryable conflict and performs
|
|
1406
|
+
no downstream request. The runtime validates the stored acceptance binding,
|
|
1407
|
+
then the pinned public-submission client performs one read and verifies the
|
|
1408
|
+
complete nested website, sidecar, source, and source-processing generations.
|
|
1409
|
+
The outer HTTP edge validates the lifecycle again before serialization.
|
|
1410
|
+
Acceptance at either boundary remains explicitly distinct from linguistic
|
|
1411
|
+
approval and publication.
|
|
1412
|
+
|
|
1413
|
+
#### Public submission sidecar reference client
|
|
1414
|
+
|
|
1415
|
+
`integrations/website_localization_cms_source_delivery_submission_dispatch_client.py`
|
|
1416
|
+
is the provider-neutral HTTPS reference adapter for backends that do not share
|
|
1417
|
+
the Python runtime. Construct it with one exact HTTPS origin, the expected
|
|
1418
|
+
sidecar capability SHA-256, the independently expected downstream public
|
|
1419
|
+
submission capability SHA-256, and a credential-header callback. The two pins
|
|
1420
|
+
must reconstruct the current canonical contract exactly; they are never
|
|
1421
|
+
interchangeable.
|
|
1422
|
+
|
|
1423
|
+
`enqueue()` accepts one complete change, cancellation, or tombstone and keeps
|
|
1424
|
+
the source-, delivery-, and client-stage retry ceilings distinct. `status()`
|
|
1425
|
+
requires the complete previously known operation, request, event, site, and
|
|
1426
|
+
source-payload identity. `lifecycle()` uses the same identity and refuses to
|
|
1427
|
+
contact the downstream service until the local status is accepted. `health()`,
|
|
1428
|
+
`readiness()`, `capabilities()`, `commercial_profile()`, and
|
|
1429
|
+
`openapi()` use their separate operator scopes. Each operational method first
|
|
1430
|
+
fetches the live capability document, accepts only the exact current closed
|
|
1431
|
+
shape, then makes one bounded request without following redirects or retrying
|
|
1432
|
+
internally.
|
|
1433
|
+
|
|
1434
|
+
`openapi()` also reconstructs the expected document from the separately pinned
|
|
1435
|
+
sidecar and downstream capability generations and requires an exact match. A
|
|
1436
|
+
peer cannot make a substituted description acceptable merely by recomputing
|
|
1437
|
+
the advertised OpenAPI hash.
|
|
1438
|
+
|
|
1439
|
+
The credential callback receives a content-free context containing the exact
|
|
1440
|
+
method, origin, path, scope, and body SHA-256 plus tenant identity where
|
|
1441
|
+
applicable. It cannot supply `Host`, framing, content, idempotency, or canonical
|
|
1442
|
+
payload-hash headers. Network and selected transient HTTP failures are marked
|
|
1443
|
+
retryable for the caller's durable scheduler; redirects, authentication,
|
|
1444
|
+
schema, identity, state, and capability failures are terminal. Every returned
|
|
1445
|
+
object is independently checked against both deployment generations and never
|
|
1446
|
+
grants localization approval or publication authority.
|
|
1447
|
+
|
|
1448
|
+
A successful response uses schema
|
|
1449
|
+
`blun.cms-source-delivery-submission-capabilities-response.v1` and includes the
|
|
1450
|
+
HTTP API schema plus the complete freshly verified capability. The adapter
|
|
1451
|
+
revalidates every operation, retry-policy field, publication semantic, both
|
|
1452
|
+
downstream pins, the exact durable website binding, and the canonical digest.
|
|
1453
|
+
It never serializes the authenticated principal. Authentication outage,
|
|
1454
|
+
runtime outage, stale hash, foreign schema, extra field, or altered semantic
|
|
1455
|
+
returns a `blun.cms-source-delivery-submission-capabilities-http-error.v1`
|
|
1456
|
+
envelope with only `BLOCK` and a stable error code.
|
|
1457
|
+
|
|
1458
|
+
`enqueue_change()` and `enqueue_removal()` persist work before transport.
|
|
1459
|
+
Their `delivery_max_attempts` controls only website-to-sidecar acceptance;
|
|
1460
|
+
their `source_max_attempts` remains the final processing ceiling; the factory's
|
|
1461
|
+
middle limit controls sidecar delivery. `status()` and `health()` describe the
|
|
1462
|
+
local acceptance outbox. `sidecar_status()`, `sidecar_health()`,
|
|
1463
|
+
`sidecar_readiness()`, `sidecar_source_status()`,
|
|
1464
|
+
`sidecar_source_health()`, `sidecar_source_readiness()`, and
|
|
1465
|
+
`sidecar_capabilities()` perform separately authenticated operational reads and
|
|
1466
|
+
never reinterpret local success as downstream completion.
|
|
1467
|
+
|
|
1468
|
+
Use `submission_status(operation, request_id)` for a single content-free
|
|
1469
|
+
projection across both acceptance queues. While the website row is pending,
|
|
1470
|
+
leased, retrying, or failed, it performs no network request and reports stage
|
|
1471
|
+
`website_acceptance`. Only after local success does it query the sidecar with
|
|
1472
|
+
the persisted operation, request, event, site, and payload hash. The response
|
|
1473
|
+
must preserve those bindings, both capability pins, the configured middle
|
|
1474
|
+
delivery ceiling, and the source-processing ceiling.
|
|
1475
|
+
|
|
1476
|
+
The projection schema is
|
|
1477
|
+
`blun.cms-source-delivery-submission-status.v2`. Its top-level status is
|
|
1478
|
+
`pending`, `failed`, or `accepted`; its stage is `website_acceptance`,
|
|
1479
|
+
`sidecar_delivery`, or `source_acceptance`. It includes the separate website
|
|
1480
|
+
and sidecar states, attempt counts and retry ceilings, the next-attempt time,
|
|
1481
|
+
lease-expiry flag, and a stable content-free error code. `accepted` means the
|
|
1482
|
+
source service has durably accepted the event. It does not mean translation,
|
|
1483
|
+
quality review, release approval, or publication succeeded.
|
|
1484
|
+
|
|
1485
|
+
The `website_capability_binding` field is independently recomputed from the
|
|
1486
|
+
validated, role-specific SQLite generation before the status is projected. It
|
|
1487
|
+
contains only the outer adapter capability hash, source-runtime hash,
|
|
1488
|
+
commercial rendering-registry hash, terminal-receiver capability hash,
|
|
1489
|
+
database role, and their canonical binding hash. A missing, changed, or
|
|
1490
|
+
malformed binding blocks locally before a sidecar status request.
|
|
1491
|
+
|
|
1492
|
+
`submission_lifecycle()` extends that accepted state with the independently
|
|
1493
|
+
validated source lifecycle. Its
|
|
1494
|
+
`blun.cms-source-delivery-submission-lifecycle.v4` projection keeps submission,
|
|
1495
|
+
source status, the verified website generation, and the verified source runtime
|
|
1496
|
+
binding separate. Missing or changed binding evidence blocks instead of
|
|
1497
|
+
returning a processing state.
|
|
1498
|
+
|
|
1499
|
+
Use `submission_readiness()` to inspect the complete durable intake path
|
|
1500
|
+
without collapsing its two independently operated workers. The method first
|
|
1501
|
+
validates the website worker's local readiness object. If that worker or its
|
|
1502
|
+
outbox is not ready, it returns `not_ready` without making a network request.
|
|
1503
|
+
Only a locally ready runtime performs the authenticated, contract-pinned
|
|
1504
|
+
sidecar readiness request.
|
|
1505
|
+
|
|
1506
|
+
The content-free
|
|
1507
|
+
`blun.cms-source-delivery-submission-readiness.v2` projection retains separate
|
|
1508
|
+
website and sidecar readiness, worker state, outbox state, and stable error
|
|
1509
|
+
code fields. It also carries the trusted sidecar and source-service capability
|
|
1510
|
+
hashes plus the locally verified website generation. Overall status is `ready`
|
|
1511
|
+
only when both workers report `running`, both
|
|
1512
|
+
outboxes report `ok`, both component error codes are absent, and the sidecar
|
|
1513
|
+
response matches the currently pinned contract. This is intake readiness; it
|
|
1514
|
+
does not assert that a particular localization or publication has completed.
|
|
1515
|
+
|
|
1516
|
+
Use `submission_pipeline_readiness()` when the website must also prove that the
|
|
1517
|
+
source localization service can process accepted work. The method evaluates
|
|
1518
|
+
the existing intake projection first. If the website worker or sidecar is not
|
|
1519
|
+
ready, `source_readiness` remains `null` and no request reaches the next layer.
|
|
1520
|
+
Only fully ready intake performs the separately authenticated, body-free
|
|
1521
|
+
`source_readiness()` operation through the sidecar.
|
|
1522
|
+
|
|
1523
|
+
The resulting
|
|
1524
|
+
`blun.cms-source-delivery-submission-pipeline-readiness.v3` object keeps the
|
|
1525
|
+
complete intake projection and source-worker projection separate, binds the
|
|
1526
|
+
current sidecar and source-service capability hashes plus the website and
|
|
1527
|
+
source runtime bindings, and reports overall
|
|
1528
|
+
`ready` only when both projections are independently ready. A stopped source
|
|
1529
|
+
worker, transport failure, malformed status combination, or capability drift
|
|
1530
|
+
blocks fail-closed. This operational probe is content-free and makes no claim
|
|
1531
|
+
that any particular locale has passed review or publication.
|
|
1532
|
+
|
|
1533
|
+
Use `submission_health()` for one content-free operational view of both
|
|
1534
|
+
durable acceptance outboxes. The runtime validates its local health object
|
|
1535
|
+
before making any network request, then retrieves the sidecar health through
|
|
1536
|
+
the owned authenticated, contract-pinned client. Invalid local state therefore
|
|
1537
|
+
blocks offline; malformed remote counters, contradictory status, and changed
|
|
1538
|
+
capability bindings also block fail-closed.
|
|
1539
|
+
|
|
1540
|
+
The `blun.cms-source-delivery-submission-health.v2` projection retains the
|
|
1541
|
+
complete whitelisted website and sidecar health snapshots separately,
|
|
1542
|
+
including counts, operation totals, due work, expired leases, terminal
|
|
1543
|
+
failures, contract mismatches, and stable error codes. Its overall status is
|
|
1544
|
+
`ok` only when both snapshots independently report `ok`. A blocked component
|
|
1545
|
+
can never be hidden by the other component's healthy state. The exact website
|
|
1546
|
+
generation binding is checked locally and included before the sidecar health
|
|
1547
|
+
request is allowed.
|
|
1548
|
+
|
|
1549
|
+
Use `submission_pipeline_health()` to extend that health view through every
|
|
1550
|
+
durable source-processing queue. The runtime evaluates the website and sidecar
|
|
1551
|
+
intake projection first. If either intake outbox is blocked, `source_health`
|
|
1552
|
+
remains `null` and no source-health request is made. Healthy intake performs a
|
|
1553
|
+
separately authenticated, body-free source-health request through the sidecar.
|
|
1554
|
+
|
|
1555
|
+
The resulting `blun.cms-source-delivery-submission-pipeline-health.v3` object
|
|
1556
|
+
keeps the intake projection and complete source-service projection separate,
|
|
1557
|
+
binds both current capability hashes and the website and source runtime
|
|
1558
|
+
bindings, and
|
|
1559
|
+
preserves `ok`, `degraded`, or
|
|
1560
|
+
`blocked` source state. Invalid counters, contradictory HTTP status, transport
|
|
1561
|
+
failure, or capability drift block fail-closed without returning content.
|
|
1562
|
+
|
|
1563
|
+
Call `replace_credential()` only during a server-side generation overlap. It
|
|
1564
|
+
updates the exact signer owned by the worker without reopening the outbox or
|
|
1565
|
+
changing either contract pin. The wrapper blocks network and storage access
|
|
1566
|
+
after close or from a forked process; each child must create a fresh runtime
|
|
1567
|
+
from host-owned configuration. Representations and stable failures contain no
|
|
1568
|
+
secret, endpoint, tenant, source text, or provider response.
|
|
1569
|
+
|
|
1570
|
+
#### Durable website submission through the sidecar
|
|
1571
|
+
|
|
1572
|
+
`integrations/website_localization_cms_source_delivery_sidecar_adapter.py`
|
|
1573
|
+
connects that sidecar client to `DurableCMSSourceDeliveryOutbox` without
|
|
1574
|
+
collapsing retry ownership. Wrap the pinned or rotating-HMAC sidecar client in
|
|
1575
|
+
`CMSSourceDeliverySidecarOutboxAdapter`, configure the sidecar's downstream
|
|
1576
|
+
`sidecar_delivery_max_attempts`, and pass the adapter to
|
|
1577
|
+
`open_durable_cms_source_delivery()` or
|
|
1578
|
+
`open_hosted_cms_source_delivery()`.
|
|
1579
|
+
|
|
1580
|
+
The runtime's `delivery_max_attempts` remains the website's ceiling for
|
|
1581
|
+
obtaining durable sidecar acceptance. `source_max_attempts` remains the source
|
|
1582
|
+
service's processing ceiling. The adapter's fixed
|
|
1583
|
+
`sidecar_delivery_max_attempts` is the independent middle ceiling used after
|
|
1584
|
+
acceptance. A transient failure reaching the sidecar therefore consumes only
|
|
1585
|
+
the outer budget.
|
|
1586
|
+
|
|
1587
|
+
The adapter derives the outbox capability binding from a canonical record of
|
|
1588
|
+
the sidecar capability pin, downstream source-service capability pin, and
|
|
1589
|
+
middle retry ceiling. Any change blocks existing active rows before network
|
|
1590
|
+
access. Only an exact sidecar acceptance envelope is projected into the
|
|
1591
|
+
outbox's private completion receipt; downstream status is never represented as
|
|
1592
|
+
completed and must still be read through the sidecar status/lifecycle APIs.
|
|
1593
|
+
Malformed acknowledgements and undeclared exceptions fail closed.
|
|
1594
|
+
|
|
1595
|
+
#### Rotatable source-delivery HMAC authentication
|
|
1596
|
+
|
|
1597
|
+
`integrations/website_localization_cms_source_delivery_auth.py` provides a
|
|
1598
|
+
complete provider-neutral authentication implementation for the client and
|
|
1599
|
+
sidecar callback contracts. It is optional: deployments may still use bearer
|
|
1600
|
+
tokens, mutual TLS, an external identity proxy, or another verifier. HMAC here
|
|
1601
|
+
authenticates transport requests; it is not a linguistic-quality signature and
|
|
1602
|
+
cannot replace either review stage or a signed publication approval.
|
|
1603
|
+
|
|
1604
|
+
Create an `HMACCredential` from a host-owned secret of at least 32 bytes, an
|
|
1605
|
+
explicit credential ID and generation, a sorted allowlist of route scopes, and
|
|
1606
|
+
the one authorized `site_id` whenever tenant scopes are present. The credential
|
|
1607
|
+
object redacts the secret from representations. Secrets are passed in memory;
|
|
1608
|
+
the module never reads, writes, generates, or rotates a live key file.
|
|
1609
|
+
|
|
1610
|
+
`SourceDeliveryHMACSigner` is the `authentication_headers` callback for
|
|
1611
|
+
`CMSSourceDeliverySidecarHTTPClient`. `SourceDeliveryHMACVerifier` is the
|
|
1612
|
+
matching `http_authenticator` callback for
|
|
1613
|
+
`open_hosted_cms_source_delivery()`. Configure both from trusted deployment
|
|
1614
|
+
state with the identical HTTPS origin, sidecar capability SHA-256, downstream
|
|
1615
|
+
source-service capability SHA-256, and accepted credential generation. The
|
|
1616
|
+
canonical proof binds those values together with the exact method, live
|
|
1617
|
+
contract path, route scope, body hash, site, event, request and payload
|
|
1618
|
+
identities, and the actual idempotency and source-payload headers.
|
|
1619
|
+
|
|
1620
|
+
For a long-lived client, use `RotatingSourceDeliveryHMACSigner` directly as
|
|
1621
|
+
the `authentication_headers` callback. Its origin, sidecar capability digest,
|
|
1622
|
+
downstream capability digest, clock policy, nonce source, and transport policy
|
|
1623
|
+
are fixed when it is constructed. `replace_credential()` validates one entire
|
|
1624
|
+
new `HMACCredential` and atomically replaces only the credential-bound signer
|
|
1625
|
+
under the same lock used to create proofs. Invalid replacement state keeps the
|
|
1626
|
+
last valid signer. The wrapper is process-bound and rejects inherited use after
|
|
1627
|
+
fork; each child must obtain its own host-supplied credential and signer.
|
|
1628
|
+
|
|
1629
|
+
Every proof has a short bounded timestamp and a random nonce. The verifier
|
|
1630
|
+
checks the HMAC with constant-time comparison and then calls
|
|
1631
|
+
`DurableHMACReplayStore.consume()` before returning a principal. Construct the
|
|
1632
|
+
store over a dedicated caller-owned SQLite connection; threaded WSGI hosts
|
|
1633
|
+
must open that connection with `check_same_thread=False`. Keep its database on
|
|
1634
|
+
the same class of private durable storage as the delivery outbox and close it
|
|
1635
|
+
only after the HTTP host has stopped. The ledger contains only credential IDs,
|
|
1636
|
+
versions, nonces, proof hashes, and validity times—never secrets, request
|
|
1637
|
+
bodies, website text, translations, or provider responses.
|
|
1638
|
+
|
|
1639
|
+
The store validates its schema and every retained row inside the same immediate
|
|
1640
|
+
transaction that consumes a nonce. Exact replay returns an invalid principal
|
|
1641
|
+
and therefore HTTP `401`. A store transaction conflict, malformed retained row,
|
|
1642
|
+
SQLite outage, or invalid clock raises a stable content-free infrastructure
|
|
1643
|
+
failure, which the sidecar maps to retryable HTTP `503` without accepting the
|
|
1644
|
+
request. Multiple credential generations may be configured simultaneously for
|
|
1645
|
+
a bounded rotation window; removing a generation retires it immediately.
|
|
1646
|
+
|
|
1647
|
+
#### Protected authenticated sidecar runtime
|
|
1648
|
+
|
|
1649
|
+
`integrations/website_localization_cms_source_delivery_auth_runtime.py`
|
|
1650
|
+
provides the production composition for the V6.67 proof. Call
|
|
1651
|
+
`open_hosted_hmac_authenticated_cms_source_delivery()` with distinct absolute
|
|
1652
|
+
outbox and replay-database paths, the provider-neutral source client, one or
|
|
1653
|
+
more explicit `HMACCredential` generations, worker identity, fixed HTTPS
|
|
1654
|
+
origin, and both trusted capability digests. The returned object owns the
|
|
1655
|
+
supervised delivery worker, sidecar WSGI application, outbox connection,
|
|
1656
|
+
authentication verifier, and replay connection as one lifecycle.
|
|
1657
|
+
|
|
1658
|
+
Import the server-side `HMACCredential` alias from this runtime module so the
|
|
1659
|
+
credential values and verifier share the exact validated contract type. The
|
|
1660
|
+
secret still enters only as host-owned in-memory bytes and is never written to
|
|
1661
|
+
either database.
|
|
1662
|
+
|
|
1663
|
+
The factory validates the complete authentication time window, credential
|
|
1664
|
+
scope, endpoint, contract pins, worker, retry policy, loop delays, SQLite
|
|
1665
|
+
timeouts, and distinct paths in memory before it opens either database. Each
|
|
1666
|
+
missing database is created exclusively with mode `0600`. Every later proof or
|
|
1667
|
+
authentication-health read rechecks the replay file's owner, type, link count,
|
|
1668
|
+
mode, device and inode, plus its safe parent chain. The runtime checks its
|
|
1669
|
+
creating process before entering a lock, serializes all connection use, and
|
|
1670
|
+
therefore rejects inherited pre-fork instances before SQLite or protected
|
|
1671
|
+
website state is touched.
|
|
1672
|
+
|
|
1673
|
+
`authentication_health()` returns only schema, status, runtime state,
|
|
1674
|
+
consumed-nonce count, and stable error code. A local failure produces a
|
|
1675
|
+
`blocked` snapshot with no count. It never includes a path, site, credential, key, request
|
|
1676
|
+
body, source text, target text, or provider output. A missing, replaced,
|
|
1677
|
+
linked, permission-weakened, corrupt, closed, or foreign-process replay store
|
|
1678
|
+
makes the sidecar return retryable HTTP `503` during authentication, before
|
|
1679
|
+
the delivery runtime parses or persists protected content.
|
|
1680
|
+
|
|
1681
|
+
Use `replace_credentials()` on either the composite runtime or its
|
|
1682
|
+
`authentication` member to rotate without stopping the delivery worker. A
|
|
1683
|
+
safe rollout proceeds in this order:
|
|
1684
|
+
|
|
1685
|
+
1. Supply the old and new server generations together.
|
|
1686
|
+
2. Call `replace_credential()` on every client instance and verify traffic.
|
|
1687
|
+
3. Drain requests already emitted with the old credential and wait out the
|
|
1688
|
+
configured proof validity and clock-skew window, unless an equivalent
|
|
1689
|
+
deployment traffic barrier proves that none remain.
|
|
1690
|
+
4. Supply only the new server generation.
|
|
1691
|
+
|
|
1692
|
+
The client signer lock serializes proof creation in one process. It cannot
|
|
1693
|
+
recall a proof already returned to the HTTP client, synchronize other fleet
|
|
1694
|
+
instances, or prove that a request has left the network. The server must
|
|
1695
|
+
therefore keep the old generation during the bounded drain window. The
|
|
1696
|
+
method materializes and validates the complete iterable, checks the replay
|
|
1697
|
+
database and process lifecycle, waits behind any in-flight authentication,
|
|
1698
|
+
and swaps exactly one fully constructed verifier. Invalid or unavailable
|
|
1699
|
+
replacement state leaves the previous verifier untouched. The same replay
|
|
1700
|
+
ledger remains open throughout, so a consumed proof stays consumed even if
|
|
1701
|
+
its credential generation is removed and later accepted again.
|
|
1702
|
+
|
|
1703
|
+
The host remains responsible for fetching trusted secret-manager values and
|
|
1704
|
+
for deciding the overlap window. The runtime does not log, persist, return, or
|
|
1705
|
+
rotate secret material, and it never reads a key file or environment variable.
|
|
1706
|
+
|
|
1707
|
+
Call `close()` only after the external HTTP server has stopped accepting new
|
|
1708
|
+
requests. The composite first signals and joins the delivery worker and closes
|
|
1709
|
+
the outbox, then closes the replay connection. If a provider call exceeds the
|
|
1710
|
+
configured worker-stop bound, the replay runtime deliberately remains open;
|
|
1711
|
+
the caller must resolve the still-running worker and retry shutdown rather
|
|
1712
|
+
than invalidating authentication underneath it.
|
|
1713
|
+
|
|
755
1714
|
Premortem: an invalid deployment could create state before discovering a bad
|
|
756
1715
|
worker or timeout; two paths could alias one database; a pre-fork service could
|
|
757
1716
|
reuse a vanished parent's lock; or a permission change could redirect the next
|
|
@@ -974,8 +1933,11 @@ text out of access logs.
|
|
|
974
1933
|
`DurableCMSReceiverStore` in
|
|
975
1934
|
`integrations/website_localization_cms_receiver_store.py` supplies a complete
|
|
976
1935
|
SQLite reference implementation for the five stateful host callbacks. It uses
|
|
977
|
-
one dedicated host-owned connection
|
|
978
|
-
|
|
1936
|
+
one dedicated host-owned connection and requires both the canonical
|
|
1937
|
+
`release_evidence_is_current` validator and the configured publisher authority
|
|
1938
|
+
through a closed signature-validation callback supplied by the receiver. The CMS
|
|
1939
|
+
registers each monotonic current source before delivery and explicitly
|
|
1940
|
+
pre-registers a tombstone against the
|
|
979
1941
|
exact active publication before deletion. Commit and delete recheck those
|
|
980
1942
|
bindings inside `BEGIN IMMEDIATE`, so the earlier resolver lookup cannot race a
|
|
981
1943
|
source change. Replays are bound to immutable delivery and payload hashes, a
|
|
@@ -983,9 +1945,18 @@ replacement preserves the last-known-good bundle until its complete locale set
|
|
|
983
1945
|
commits. The successful replacement transaction then securely deletes the
|
|
984
1946
|
superseded payload and locale rows while retaining only content-free replay
|
|
985
1947
|
evidence; any cleanup failure rolls the switch back to the previous active
|
|
986
|
-
bundle. Explicit deletion follows the same content-minimizing rule. The store
|
|
987
|
-
|
|
988
|
-
|
|
1948
|
+
bundle. Explicit deletion follows the same content-minimizing rule. The store
|
|
1949
|
+
retains the exact canonical publisher signature with each active payload. Its
|
|
1950
|
+
health callback validates schema, SQLite integrity, canonical payloads,
|
|
1951
|
+
publisher signatures, locale rows, active pointers, the current release-evidence
|
|
1952
|
+
contract, approval expiry, and tombstone state before confirming the probe.
|
|
1953
|
+
Active reads and idempotent publication replay run the same authorization checks
|
|
1954
|
+
after restart. A v1 database migrates to v2 without inventing missing
|
|
1955
|
+
signatures: signatureless active legacy rows remain blocked and unhealthy but
|
|
1956
|
+
can still be structurally tombstoned. Tombstone
|
|
1957
|
+
registration and deletion retain a structural-only path so an expired or
|
|
1958
|
+
contract-stale active bundle can always be removed without becoming publishable.
|
|
1959
|
+
Source and tombstone expectations
|
|
989
1960
|
carry separate canonical hashes, so a syntactically valid field substitution
|
|
990
1961
|
also blocks. `read_active_bundle` is for trusted
|
|
991
1962
|
CMS rendering code only. It requires the complete trusted publication
|
|
@@ -1037,7 +2008,7 @@ disabled, so a CMS can fail closed before submitting work. The object uses
|
|
|
1037
2008
|
over every other canonical field. Paths and schemas come from the same runtime
|
|
1038
2009
|
constants used for routing; they are not copied into a second configuration.
|
|
1039
2010
|
|
|
1040
|
-
The nested `blun.website-localization-capabilities.
|
|
2011
|
+
The nested `blun.website-localization-capabilities.v9` object carries a
|
|
1041
2012
|
`sha256` value over all its other canonical fields. Consumers can pin that
|
|
1042
2013
|
digest for a deployment and deliberately reconfigure when it changes. The
|
|
1043
2014
|
runtime rebuilds and validates the complete registry on every read; duplicate,
|
|
@@ -1045,40 +2016,275 @@ missing, noncanonical, or profile-mismatched entries return a fail-closed `503`
|
|
|
1045
2016
|
without a partial locale list.
|
|
1046
2017
|
|
|
1047
2018
|
Within it, `commercial_profile` is a separately hashed
|
|
1048
|
-
`translate-native.commercial-capabilities.
|
|
1049
|
-
hashed `
|
|
2019
|
+
`translate-native.commercial-capabilities.v15` object. Its nested and separately
|
|
2020
|
+
hashed `review_evidence_contract` defines the exact private report fields,
|
|
2021
|
+
coverage values, offer registry, Unicode code-point spans, item relations,
|
|
2022
|
+
ten-dimension order, limits, per-offer verdict matrix, aggregate-status
|
|
2023
|
+
derivation, and structural-only trust
|
|
2024
|
+
boundary without publishing any project content. Source-fidelity providers,
|
|
2025
|
+
CMS backends and the portable checker can therefore consume one canonical
|
|
2026
|
+
shape rather than inferring it from examples or prompt prose. The sibling
|
|
2027
|
+
`review_summary_contract` defines the exact content-free result schema,
|
|
1050
2028
|
field set, verified/review-required state invariant, ten allowed ordered
|
|
1051
|
-
review dimensions,
|
|
1052
|
-
content. A CMS or independent-review adapter
|
|
1053
|
-
escalation without receiving project prices,
|
|
1054
|
-
|
|
2029
|
+
review dimensions, exact review-evidence-contract/source/target/profile/
|
|
2030
|
+
locale-quality/evidence hash semantics, and excluded sensitive content. A CMS or independent-review adapter
|
|
2031
|
+
can validate targeted commercial escalation without receiving project prices,
|
|
2032
|
+
brands, source/target text, spans,
|
|
2033
|
+
or reviewer prose. The evidence contract now requires a canonical registry of
|
|
2034
|
+
unique offer IDs with ordered, non-overlapping source and target regions.
|
|
2035
|
+
Every proposition span must remain inside its named offer, and equivalent
|
|
2036
|
+
offer-assignment evidence must cover every registry entry exactly once.
|
|
2037
|
+
Every dimension must also acknowledge every registered offer exactly once in
|
|
2038
|
+
registry order. Equivalent, changed, and uncertain offer verdicts require
|
|
2039
|
+
their own offer-bound evidence; the validator derives and checks the global
|
|
2040
|
+
dimension status so a report cannot hide an omitted second offer behind a
|
|
2041
|
+
first offer's global pass.
|
|
2042
|
+
Discontiguous regions remain available for linked conditions and footnotes;
|
|
2043
|
+
uncertain semantic boundaries still route to independent review. Any registry
|
|
2044
|
+
or digest drift blocks the whole discovery
|
|
1055
2045
|
response rather than advertising a partial contract.
|
|
1056
2046
|
|
|
2047
|
+
Commercial plan v5 and job v5 identities bind the exact review-evidence,
|
|
2048
|
+
content-free review-routing, and content-free review-resolution contract
|
|
2049
|
+
SHA-256 values. Changing any contract produces new job, idempotency, and plan identities;
|
|
2050
|
+
the worker, queue health monitor, and pre-lease validator reconstruct the
|
|
2051
|
+
current contracts and reject stale jobs before provider access. Non-commercial
|
|
2052
|
+
jobs carry none of the commercial digests.
|
|
2053
|
+
|
|
2054
|
+
The sibling `review_routing_contract` defines the private actionable route as
|
|
2055
|
+
a separately hashed machine contract. It fixes exact Unicode code-point
|
|
2056
|
+
offsets with exclusive ends, complete source and target lengths, one ordered
|
|
2057
|
+
entry per opaque registry position, non-overlap, private-value exclusions, and
|
|
2058
|
+
the non-authoritative trust boundary. Every private route carries this exact
|
|
2059
|
+
digest. The runtime reconstructs it before evidence or receipt network access;
|
|
2060
|
+
the public capability exposes only the contract, never actual route spans.
|
|
2061
|
+
|
|
2062
|
+
The `publication_http.release_evidence_contract` is independently hashed and
|
|
2063
|
+
fixes the complete public evidence field set, its target, digest, and evidence
|
|
2064
|
+
lineage bindings, commercial nullability, signed publication container, and
|
|
2065
|
+
excluded private content. The runtime compares the whole object with its
|
|
2066
|
+
canonical registry, so removing or reordering a field and recomputing both
|
|
2067
|
+
public hashes still blocks capability discovery before publication.
|
|
2068
|
+
|
|
2069
|
+
The separately hashed `review_resolution_contract` makes the escalation result
|
|
2070
|
+
fully machine-readable. It requires the exact ordered unresolved dimensions,
|
|
2071
|
+
one resolved status and either a qualified-human route with a null provider or
|
|
2072
|
+
an independent-model route with the exact provider ID, model ID and model
|
|
2073
|
+
version distinct from the primary provider. The result binds the exact
|
|
2074
|
+
commercial profile and advertised resolution-contract SHA-256, and carries the
|
|
2075
|
+
primary provider identity so the CMS can verify that distinction itself. Only
|
|
2076
|
+
the verified receipt SHA-256 crosses the publication boundary. Raw receipts,
|
|
2077
|
+
credentials, qualified-human identity, reviewer prose, project prices, brands,
|
|
2078
|
+
source text and target text are excluded.
|
|
2079
|
+
Its digest is already fixed by the commercial plan and per-locale job, then
|
|
2080
|
+
carried unchanged through the worker result and evidence request. A later
|
|
2081
|
+
resolution-policy revision cannot reinterpret queued or completed work: stale
|
|
2082
|
+
bindings block before lease, provider access, receipt verification, or signed
|
|
2083
|
+
approval.
|
|
2084
|
+
|
|
2085
|
+
The commercial capability additionally requires schema
|
|
2086
|
+
`translate-native.commercial-locale-quality-profile.v2` in every commercial
|
|
2087
|
+
job. One distinct version and digest is derived for each advertised EU locale
|
|
2088
|
+
from that locale's native, fidelity, adversarial and source-reference profile.
|
|
2089
|
+
The full object is bound into the job ID and all three provider requests; its
|
|
2090
|
+
version and digest remain in signed quality evidence. A stale, substituted or
|
|
2091
|
+
mutated locale profile blocks before any provider call.
|
|
2092
|
+
|
|
2093
|
+
The profile includes a canonical
|
|
2094
|
+
`translate-native.commercial-rendering-reference.v1` derived from the tagged
|
|
2095
|
+
Unicode CLDR 48 numbers data for that exact target profile. Its default and
|
|
2096
|
+
native numbering systems, grouping threshold, symbols, and decimal, percentage,
|
|
2097
|
+
currency, ISO-currency, approximation, limit, and range patterns are sent to
|
|
2098
|
+
all three provider phases and covered by the profile digest. This is rendering
|
|
2099
|
+
guidance only: deterministic punctuation or numeric regex matching is not
|
|
2100
|
+
semantic proof, equivalent written forms remain eligible, and uncertainty is
|
|
2101
|
+
routed to independent model or qualified native-domain review.
|
|
2102
|
+
|
|
2103
|
+
The separately hashed `commercial_rendering_registry` makes those exact
|
|
2104
|
+
references available to CMS and website clients without exposing localized
|
|
2105
|
+
content. It contains all 24 locales in canonical order and binds each reference
|
|
2106
|
+
to the exact commercial locale-profile version and digest advertised in the
|
|
2107
|
+
same response. The runtime reconstructs and compares the complete registry
|
|
2108
|
+
before returning capabilities; a missing, reordered, altered, or merely
|
|
2109
|
+
rehashed entry returns `503` without a partial registry. Consumers must still
|
|
2110
|
+
treat these values as display guidance and route uncertain semantic equality to
|
|
2111
|
+
the configured independent review path.
|
|
2112
|
+
|
|
2113
|
+
For publication, `blun.website-localization-release-evidence.v14` carries the
|
|
2114
|
+
canonical release-evidence-contract SHA-256, content-free
|
|
2115
|
+
`evidence_request_id` and `evidence_revision` plus the compact universal
|
|
2116
|
+
`quality_profile` binding `{locale, version, sha256}`. The receiver recomputes
|
|
2117
|
+
that exact current target-locale binding for every content type before host
|
|
2118
|
+
code, and the durable store repeats the lookup on active reads, health checks,
|
|
2119
|
+
and idempotent replay while keeping stale bundles safely tombstonable.
|
|
2120
|
+
|
|
2121
|
+
Commercial content additionally carries its separate compact
|
|
2122
|
+
`commercial_quality_profile` binding `{profile, version, sha256}` and the exact
|
|
2123
|
+
current routing and resolution-contract SHA-256 values. The resolution-contract
|
|
2124
|
+
digest is present for every commercial result, including `verified` results,
|
|
2125
|
+
so downstream systems can prove the escalation policy that governed the
|
|
2126
|
+
approval. All commercial fields must be null for every other content type. The
|
|
2127
|
+
release service and reference CMS receiver recompute the canonical contract
|
|
2128
|
+
digest before publication and host code; a prior signed approval cannot be
|
|
2129
|
+
rewrapped under a newer contract. A syntactically valid digest, a binding from
|
|
2130
|
+
another EU locale, or a prior profile generation is not accepted. An unresolved
|
|
2131
|
+
commercial summary additionally requires
|
|
2132
|
+
`commercial_review_resolution` with the exact ordered dimensions, a
|
|
2133
|
+
commercial profile and resolution-contract SHA-256, a `qualified_human` or
|
|
2134
|
+
`independent_model` method, the verified receipt hash, the primary provider
|
|
2135
|
+
binding, and the independent provider binding only for the model route. The CMS
|
|
2136
|
+
requires the two provider IDs to differ. Verified commercial summaries and
|
|
2137
|
+
non-commercial content require this field to be `null`. Raw
|
|
2138
|
+
receipts, qualified-human identities and reviewer prose are never published.
|
|
2139
|
+
|
|
2140
|
+
The commercial summary exposes unresolved offers only as zero-based positions
|
|
2141
|
+
in the private offer registry, grouped by ordered review dimension. It does not
|
|
2142
|
+
publish configured offer identifiers. The resolution must echo the exact
|
|
2143
|
+
ordered position scope; malformed, stale, or substituted scope blocks before
|
|
2144
|
+
CMS persistence. A dimension may remain review-required with no position when
|
|
2145
|
+
global uncertainty or an empty registry prevents safe offer identification.
|
|
2146
|
+
The quality-evidence request and receipt verifier privately receive a separate
|
|
2147
|
+
text-free routing object that maps those positions to exact source and target
|
|
2148
|
+
Unicode code-point spans. It is bound into request and receipt identities but
|
|
2149
|
+
is never included in the public capability or CMS release-evidence value.
|
|
2150
|
+
|
|
1057
2151
|
```json
|
|
1058
2152
|
{
|
|
1059
2153
|
"capabilities": {
|
|
1060
2154
|
"change_schema": "blun.cms-content-change.v2",
|
|
1061
2155
|
"cancellation_schema": "blun.cms-content-cancellation.v1",
|
|
1062
2156
|
"commercial_profile": {
|
|
1063
|
-
"profile": "translate-native.commercial.
|
|
2157
|
+
"profile": "translate-native.commercial.v13",
|
|
2158
|
+
"locale_quality_profile": {
|
|
2159
|
+
"schema": "translate-native.commercial-locale-quality-profile.v2",
|
|
2160
|
+
"required": true,
|
|
2161
|
+
"binding_fields": ["locale", "version", "commercial_profile", "quality_profile_version", "quality_profile_sha256", "rendering_reference", "sha256"],
|
|
2162
|
+
"rendering_reference": {"schema": "translate-native.commercial-rendering-reference.v1", "authority": "Unicode CLDR", "version": "48", "purpose": "target-locale-rendering-guidance", "semantic_proof": false, "unresolved_route": "independent-model-or-qualified-native-domain-review"},
|
|
2163
|
+
"required_commercial_checks": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"],
|
|
2164
|
+
"provider_phases": ["transcreation", "target_native", "source_fidelity"],
|
|
2165
|
+
"tamper_policy": "block-before-provider"
|
|
2166
|
+
},
|
|
2167
|
+
"review_evidence_contract": {
|
|
2168
|
+
"checks": {
|
|
2169
|
+
"exact_dimension_set": true,
|
|
2170
|
+
"item": {
|
|
2171
|
+
"duplicates": "forbidden-per-dimension",
|
|
2172
|
+
"explanation": "non-empty-maximum-2000-code-points",
|
|
2173
|
+
"matched_requires": "source-and-target-spans",
|
|
2174
|
+
"offer": "registered-offer-id",
|
|
2175
|
+
"relations": ["matched", "source_only", "target_only"],
|
|
2176
|
+
"required_fields": ["offer", "relation", "source_span", "target_span", "explanation"],
|
|
2177
|
+
"source_only_requires": "source-span-and-null-target-span",
|
|
2178
|
+
"span_containment": "inside-named-offer-region",
|
|
2179
|
+
"target_only_requires": "null-source-span-and-target-span"
|
|
2180
|
+
},
|
|
2181
|
+
"max_items_per_dimension": 1000,
|
|
2182
|
+
"offer_assignment": {
|
|
2183
|
+
"equivalent": "exactly-one-matched-item-per-registered-offer",
|
|
2184
|
+
"other_equivalent_checks_require_equivalent_assignment": true
|
|
2185
|
+
},
|
|
2186
|
+
"offer_statuses": {
|
|
2187
|
+
"coverage": "exactly-one-per-registered-offer",
|
|
2188
|
+
"field": "offer_statuses",
|
|
2189
|
+
"global_status": "changed-then-uncertain-then-equivalent-then-not_present",
|
|
2190
|
+
"item_required_fields": ["offer", "status"],
|
|
2191
|
+
"items_must_match_offer_status": true,
|
|
2192
|
+
"order": "offer-registry-order",
|
|
2193
|
+
"statuses": ["equivalent", "not_present", "changed", "uncertain"]
|
|
2194
|
+
},
|
|
2195
|
+
"required_dimensions": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"],
|
|
2196
|
+
"status_items": {"changed": "one-or-more-specific", "equivalent": "one-or-more-matched", "not_present": "empty", "uncertain": "one-or-more-specific"},
|
|
2197
|
+
"statuses": ["equivalent", "not_present", "changed", "uncertain"]
|
|
2198
|
+
},
|
|
2199
|
+
"content_policy": {"project_brands": false, "project_prices": false, "reviewer_prose": false, "source_spans": false, "source_text": false, "target_spans": false, "target_text": false},
|
|
2200
|
+
"coverage": {"allowed": ["complete", "uncertain"], "complete": "every-proposition-and-offer-association-reviewed", "uncertain": "independent-review-required"},
|
|
2201
|
+
"offer_registry": {
|
|
2202
|
+
"field": "offers",
|
|
2203
|
+
"identifier": {"pattern": "^[A-Za-z0-9_.:-]{1,256}$", "unique": true},
|
|
2204
|
+
"item_required_fields": ["id", "source_spans", "target_spans"],
|
|
2205
|
+
"max_items": 1000,
|
|
2206
|
+
"regions": {"at_least_one_side_non_empty": true, "discontiguous": true, "fields": ["source_spans", "target_spans"], "non_empty_text": true, "ordered": true, "overlap": "forbidden-within-and-across-offers", "span_format": "zero-based-unicode-code-points-exclusive-end"}
|
|
2207
|
+
},
|
|
2208
|
+
"profile": "translate-native.commercial.v13",
|
|
2209
|
+
"required_fields": ["schema", "coverage", "offers", "checks"],
|
|
2210
|
+
"result_schema": "translate-native.commercial.v13",
|
|
2211
|
+
"schema": "translate-native.commercial-review-evidence-capabilities.v2",
|
|
2212
|
+
"sha256": "<sha256>",
|
|
2213
|
+
"trust_boundary": {"numeric_regex_semantic_proof": false, "publication_authority": false, "semantic_truth": false, "unresolved_route": "independent-model-or-qualified-native-domain-review", "validates": "structure-offsets-and-verdict-consistency"}
|
|
2214
|
+
},
|
|
2215
|
+
"review_evidence_schema": "translate-native.commercial.v13",
|
|
1064
2216
|
"review_summary_contract": {
|
|
1065
2217
|
"content_policy": {"project_brands": false, "project_prices": false, "reviewer_prose": false, "source_spans": false, "source_text": false, "target_spans": false, "target_text": false},
|
|
1066
|
-
"evidence_sha256": {"algorithm": "sha-256", "canonicalization": "utf-8-json-sort-keys-no-insignificant-whitespace", "covers": "complete-commercial-review-evidence"},
|
|
1067
|
-
"profile": "translate-native.commercial.
|
|
1068
|
-
"required_fields": ["schema", "profile", "status", "review_required_dimensions", "evidence_sha256"],
|
|
1069
|
-
"result_schema": "translate-native.commercial-review-summary.
|
|
2218
|
+
"evidence_sha256": {"algorithm": "sha-256", "binding_fields": ["schema", "profile", "review_evidence_contract_sha256", "target_locale", "commercial_quality_profile_version", "commercial_quality_profile_sha256", "source_sha256", "target_sha256", "evidence"], "binding_schema": "translate-native.commercial-review-evidence-binding.v5", "canonicalization": "utf-8-json-sort-keys-no-insignificant-whitespace", "covers": ["commercial-profile", "exact-review-evidence-contract", "exact-target-locale", "commercial-quality-profile-generation", "exact-source-sha256", "exact-target-sha256", "offer-registry-and-proposition-assignment", "complete-commercial-review-evidence"], "text_hashing": "exact-utf-8"},
|
|
2219
|
+
"profile": "translate-native.commercial.v13",
|
|
2220
|
+
"required_fields": ["schema", "profile", "status", "review_required_dimensions", "offer_count", "review_required_offers", "review_evidence_contract_sha256", "evidence_sha256"],
|
|
2221
|
+
"result_schema": "translate-native.commercial-review-summary.v6",
|
|
2222
|
+
"review_evidence_contract_sha256": {"algorithm": "sha-256", "equals": "<review-evidence-contract-sha256>", "purpose": "reject-stale-or-reinterpreted-private-evidence"},
|
|
2223
|
+
"offer_count": {"maximum": 1000, "meaning": "opaque-offer-registry-size", "minimum": 0},
|
|
1070
2224
|
"review_required_dimensions": {"allowed": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"], "order": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"], "unique": true},
|
|
1071
|
-
"
|
|
2225
|
+
"review_required_offers": {"configured_offer_identifiers_published": false, "dimension_must_be_review_required": true, "dimension_order": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"], "item_required_fields": ["dimension", "offer_indexes"], "offer_indexes": {"maximum_exclusive": 1000, "meaning": "zero-based-opaque-offer-registry-position", "minimum": 0, "order": "ascending", "unique": true}},
|
|
2226
|
+
"schema": "translate-native.commercial-review-summary-capabilities.v7",
|
|
1072
2227
|
"sha256": "<sha256>",
|
|
1073
|
-
"statuses": {"review_required": {"requires_independent_review": true, "review_required_dimensions": "one-or-more"}, "verified": {"review_required_dimensions": "empty"}}
|
|
2228
|
+
"statuses": {"review_required": {"requires_independent_review": true, "review_required_dimensions": "one-or-more", "review_required_offers": "zero-or-more"}, "verified": {"review_required_dimensions": "empty", "review_required_offers": "empty"}}
|
|
1074
2229
|
},
|
|
1075
|
-
"
|
|
2230
|
+
"review_routing_contract": {
|
|
2231
|
+
"applies_when": {"offer_count": "exact-review-summary-offer-count", "review_summary_status": "review_required"},
|
|
2232
|
+
"content_policy": {"configured_offer_identifiers": false, "project_brands": false, "project_prices": false, "reviewer_prose": false, "source_text": false, "target_text": false},
|
|
2233
|
+
"offers": {"coverage": "exactly-one-per-registered-offer", "item_required_fields": ["offer_index", "source_spans", "target_spans"], "offer_index": {"maximum_exclusive": 1000, "meaning": "zero-based-opaque-offer-registry-position", "minimum": 0, "order": "ascending", "unique": true}, "order": "offer-registry-order", "regions": {"at_least_one_side_non_empty": true, "discontiguous": true, "fields": ["source_spans", "target_spans"], "non_empty_text": true, "ordered": true, "overlap": "forbidden-within-and-across-offers", "span_format": "zero-based-unicode-code-points-exclusive-end"}},
|
|
2234
|
+
"profile": "translate-native.commercial.v13",
|
|
2235
|
+
"required_fields": ["schema", "profile", "contract_sha256", "offer_count", "source_length", "target_length", "offers"],
|
|
2236
|
+
"result_schema": "translate-native.commercial-review-routing.v2",
|
|
2237
|
+
"schema": "translate-native.commercial-review-routing-capabilities.v1",
|
|
2238
|
+
"sha256": "<sha256>",
|
|
2239
|
+
"text_lengths": {"fields": ["source_length", "target_length"], "must_equal_complete_texts": true, "unit": "unicode-code-points"},
|
|
2240
|
+
"trust_boundary": {"public_release_evidence": false, "publication_authority": false, "route_values": "private-evidence-and-receipt-boundary-only", "semantic_truth": false, "validates": "shape-offsets-order-count-and-text-lengths"}
|
|
2241
|
+
},
|
|
2242
|
+
"review_routing_schema": "translate-native.commercial-review-routing.v2",
|
|
2243
|
+
"review_resolution_contract": {
|
|
2244
|
+
"applies_when": {"review_summary_status": "review_required", "reviewed_dimensions": "exact-ordered-review-summary-dimensions", "reviewed_offer_count": "exact-review-summary-offer-count", "reviewed_offers": "exact-ordered-review-summary-offer-scope"},
|
|
2245
|
+
"content_policy": {"project_brands": false, "project_prices": false, "qualified_human_identity": false, "raw_receipt": false, "reviewer_prose": false, "source_text": false, "target_text": false},
|
|
2246
|
+
"methods": {"independent_model": {"primary_provider": "required", "provider": "required", "provider_id_must_differ_from_primary_provider": true, "receipt": "verified-independent-model-review"}, "qualified_human": {"primary_provider": "required", "provider": "null", "receipt": "verified-qualified-human-review"}},
|
|
2247
|
+
"profile": "translate-native.commercial.v13",
|
|
2248
|
+
"provider_identity": {"credentials_published": false, "fields": ["id", "model_id", "model_version"], "primary_provider": "required"},
|
|
2249
|
+
"receipt_sha256": {"algorithm": "sha-256", "covers": "exact-verified-review-receipt", "raw_receipt_published": false},
|
|
2250
|
+
"required_fields": ["schema", "profile", "contract_sha256", "status", "reviewed_dimensions", "reviewed_offer_count", "reviewed_offers", "method", "receipt_sha256", "primary_provider", "provider"],
|
|
2251
|
+
"result_schema": "translate-native.commercial-review-resolution.v4",
|
|
2252
|
+
"reviewed_dimensions": {"allowed": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"], "order": ["amount_currency", "discount_basis", "qualifiers", "tax_status", "billing_interval", "commitment", "renewal", "cancellation", "conditions", "offer_assignment"], "unique": true, "must_equal_review_summary": true},
|
|
2253
|
+
"reviewed_offer_count": {"must_equal_review_summary": true},
|
|
2254
|
+
"reviewed_offers": {"configured_offer_identifiers_published": false, "must_equal_review_summary": true},
|
|
2255
|
+
"schema": "translate-native.commercial-review-resolution-capabilities.v4",
|
|
2256
|
+
"sha256": "<sha256>",
|
|
2257
|
+
"status": "resolved"
|
|
2258
|
+
},
|
|
2259
|
+
"review_resolution_schema": "translate-native.commercial-review-resolution.v4",
|
|
2260
|
+
"schema": "translate-native.commercial-capabilities.v15",
|
|
1076
2261
|
"sha256": "<sha256>"
|
|
1077
2262
|
},
|
|
2263
|
+
"commercial_rendering_registry": {
|
|
2264
|
+
"commercial_profile": "translate-native.commercial.v13",
|
|
2265
|
+
"content_policy": {"credentials": false, "project_brands": false, "project_prices": false, "source_text": false, "target_text": false},
|
|
2266
|
+
"locales": [{
|
|
2267
|
+
"commercial_quality_profile": {"sha256": "<sha256>", "version": "commercial-eu-mt-MT-2026-09-2"},
|
|
2268
|
+
"locale": "mt-MT",
|
|
2269
|
+
"rendering_reference": {
|
|
2270
|
+
"locale": "mt-MT",
|
|
2271
|
+
"minimum_grouping_digits": 1,
|
|
2272
|
+
"native_numbering_system": "latn",
|
|
2273
|
+
"numbering_system": "latn",
|
|
2274
|
+
"patterns": {"currency": "¤#,##0.00", "decimal": "#,##0.###", "percent": "#,##0%", "range": "{0}–{1}"},
|
|
2275
|
+
"schema": "translate-native.commercial-rendering-reference.v1",
|
|
2276
|
+
"source": {"authority": "Unicode CLDR", "locale": "mt", "version": "48"},
|
|
2277
|
+
"symbols": {"decimal": ".", "group": ","}
|
|
2278
|
+
}
|
|
2279
|
+
}],
|
|
2280
|
+
"schema": "translate-native.commercial-rendering-registry.v1",
|
|
2281
|
+
"sha256": "<sha256>",
|
|
2282
|
+
"source": {"authority": "Unicode CLDR", "version": "48"}
|
|
2283
|
+
},
|
|
1078
2284
|
"content_types": ["commercial", "cta", "documentation", "headline", "legal", "marketing", "seo", "ui"],
|
|
1079
2285
|
"default_target_policy": "all-eu-official-locales-except-source-language",
|
|
1080
2286
|
"eu_language_source": "https://european-union.europa.eu/principles-countries-history/languages_en",
|
|
1081
|
-
"job_schema": "blun.website-localization-job.
|
|
2287
|
+
"job_schema": "blun.website-localization-job.v5",
|
|
1082
2288
|
"locales": [{
|
|
1083
2289
|
"direction": "ltr",
|
|
1084
2290
|
"eu_code": "MT",
|
|
@@ -1087,9 +2293,11 @@ response rather than advertising a partial contract.
|
|
|
1087
2293
|
"native_name": "Malti",
|
|
1088
2294
|
"quality_profile_sha256": "<sha256>",
|
|
1089
2295
|
"quality_profile_version": "eu-mt-MT-2026-09-1",
|
|
2296
|
+
"commercial_quality_profile_sha256": "<sha256>",
|
|
2297
|
+
"commercial_quality_profile_version": "commercial-eu-mt-MT-2026-09-2",
|
|
1090
2298
|
"script": "Latn"
|
|
1091
2299
|
}],
|
|
1092
|
-
"plan_schema": "blun.website-localization-plan.
|
|
2300
|
+
"plan_schema": "blun.website-localization-plan.v5",
|
|
1093
2301
|
"publication_http": {
|
|
1094
2302
|
"binding_headers": [
|
|
1095
2303
|
{"binding": "delivery_id", "name": "Idempotency-Key"},
|
|
@@ -1112,14 +2320,48 @@ response rather than advertising a partial contract.
|
|
|
1112
2320
|
"response_schema": "blun.cms-localization-publication-http-ack.v1"
|
|
1113
2321
|
}],
|
|
1114
2322
|
"request_content_type": "application/json; charset=utf-8",
|
|
1115
|
-
"
|
|
2323
|
+
"release_evidence_contract": {
|
|
2324
|
+
"bindings": {
|
|
2325
|
+
"lineage_fields": ["evidence_request_id", "evidence_revision"],
|
|
2326
|
+
"quality_profile": "exact-current-target-locale-quality-profile",
|
|
2327
|
+
"sha256_fields": ["release_evidence_contract_sha256", "target_sha256", "result_sha256", "approval_sha256", "quality_receipt_sha256", "commercial_review_routing_contract_sha256", "commercial_review_resolution_contract_sha256"],
|
|
2328
|
+
"signed_container": "blun.cms-localization-publication.v3",
|
|
2329
|
+
"target_identity_fields": ["job_id", "target_locale", "target_sha256", "approval_id"]
|
|
2330
|
+
},
|
|
2331
|
+
"commercial_scope": {
|
|
2332
|
+
"content_type": "commercial",
|
|
2333
|
+
"non_commercial_fields": "all-null",
|
|
2334
|
+
"quality_profile": "exact-current-target-locale-commercial-quality-profile",
|
|
2335
|
+
"required_non_null": ["commercial_profile", "commercial_quality_profile", "commercial_review", "commercial_review_routing_contract_sha256", "commercial_review_resolution_contract_sha256"],
|
|
2336
|
+
"review_evidence_contract_sha256": "exact-current-public-commercial-evidence-contract",
|
|
2337
|
+
"review_resolution_contract_sha256": "exact-current-public-commercial-resolution-contract",
|
|
2338
|
+
"resolution": "required-only-when-review-required"
|
|
2339
|
+
},
|
|
2340
|
+
"content_policy": {
|
|
2341
|
+
"authentication_material": false,
|
|
2342
|
+
"project_brands": false,
|
|
2343
|
+
"project_prices": false,
|
|
2344
|
+
"raw_receipt": false,
|
|
2345
|
+
"commercial_review_routing": false,
|
|
2346
|
+
"reviewer_identity": false,
|
|
2347
|
+
"reviewer_prose": false,
|
|
2348
|
+
"source_text": false,
|
|
2349
|
+
"target_text": false
|
|
2350
|
+
},
|
|
2351
|
+
"release_evidence_schema": "blun.website-localization-release-evidence.v14",
|
|
2352
|
+
"required_fields": ["schema", "release_evidence_contract_sha256", "job_id", "target_locale", "target_sha256", "approval_id", "content_type", "result_sha256", "approval_sha256", "quality_receipt_sha256", "evidence_request_id", "evidence_revision", "quality_profile", "commercial_profile", "commercial_quality_profile", "commercial_review", "commercial_review_routing_contract_sha256", "commercial_review_resolution_contract_sha256", "commercial_review_resolution"],
|
|
2353
|
+
"schema": "blun.website-localization-release-evidence-capabilities.v8",
|
|
2354
|
+
"sha256": "<sha256>",
|
|
2355
|
+
"tamper_policy": "reject-complete-publication-before-host-commit"
|
|
2356
|
+
},
|
|
2357
|
+
"release_evidence_schema": "blun.website-localization-release-evidence.v14",
|
|
1116
2358
|
"response_content_types": ["application/json", "application/json; charset=utf-8"],
|
|
1117
|
-
"schema": "blun.cms-localization-publication-http-capabilities.
|
|
2359
|
+
"schema": "blun.cms-localization-publication-http-capabilities.v5",
|
|
1118
2360
|
"sha256": "<sha256>"
|
|
1119
2361
|
},
|
|
1120
2362
|
"publication_schema": "blun.cms-localization-publication.v3",
|
|
1121
2363
|
"quality_passes": ["target_native", "source_fidelity"],
|
|
1122
|
-
"schema": "blun.website-localization-capabilities.
|
|
2364
|
+
"schema": "blun.website-localization-capabilities.v9",
|
|
1123
2365
|
"sha256": "<sha256>"
|
|
1124
2366
|
},
|
|
1125
2367
|
"api_contract": {
|