/changelog/ · Every release, newest first
The releases, in one place.
This page aggregates the releases of every harness crate on crates.io, newest first and grouped by month. It is generated from the same snapshot of each crate’s CHANGELOG.md that backs the History section of the module pages. crates.io remains the authoritative record of what shipped, and each crate’s full history — unreleased work included — lives on its module page; crates whose CHANGELOGs are not in the snapshot do not appear here.
61 crates, 260 releases, 6 Sep 2026 to 19 Oct 2026, at snapshot commit 0c5560b.
October 2026
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- update Cargo.lock dependencies
Dependency updates only.
Dependency updates only.
Other
Added
- A
UrlSafetyport (issue #857).checkasks whether one URL is safe to fetch — malware, social engineering, unwanted software — andcheck_manybatches the ask, verdicts in input order. Limits are checked locally before any network call bycheck_url/check_batch, which refuse withUrlSafetyError::LimitExceeded(2 048-byte URLs, batches of 500 — Safe Browsing v4's ceiling). The privacy contract is the port's first doc: the checked URL is a secret, so no implementation may log it or place it in an error string, and the one variant carrying provider text is scrubbed throughscrub_textinDisplay.CachedUrlSafetydecorates any implementation with a bounded,Clock-driven TTL cache that honours the provider's advised retention and never holds its lock across anawait. The port only: no provider adapter ships yet, so the Google Safe Browsing / Web Risk adapter issue #857 asks for is still to come.
- A
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- updated the following local packages: cratefield-secrets
- Key-reference signing port (
KeySigner), payloads (EvmTransaction,UserOperation,Eip712,SolanaMessage) with locally computed signing hashes,StaticGuardrails, theMemorySignAudithash chain, theGuardedSignercomposition, theSecretsSignersession-key provider, and thefakes/conformancekit (issue #761).
Dependency updates only.
Dependency updates only.
Dependency updates only.
Added
- module-owlpost verified Owlpost event receiver with typed inbound mail and delivery events (#673) (#853)
- text-guard protect links, hashtags and caller-supplied spans (#836) (#851)
- text-guard keep names, numbers, quotes and code across a model rewrite, and a word diff that keeps them whole (#836) (#837)
- telegram a
telegramfeature that re-exportscratefield-adapter-telegramascratefield::telegram, and atelegram-eventsfeature that re-exportscratefield-module-telegramascratefield::telegram_events: the Telegram Bot API adapter and the webhook, account-linking and consent-button module (#764) - sealed a
sealedfeature that re-exportscratefield-module-sealedascratefield::sealed: the server half of client-side sealed blobs, with opaque ciphertext at rest, crypto-shred erasure and no server-side recovery (#757) - guardrails a
guardrailsfeature that re-exportscratefield-module-guardrailsascratefield::guardrails: the policy engine every automated value-moving action must pass (#763) - signer a
signerfeature that re-exportscratefield-signerascratefield::signer: signing by key reference behind guardrails and an audit chain, with session keys held in the Secrets store (#761) - turnkey a
turnkeyfeature that re-exportscratefield-adapter-turnkeyascratefield::turnkey: the signer port's Turnkey provider, delegated access under policy (#761)
Other
- module-sealed + @cratefield/sealed: zero-knowledge sealed blobs (passkey PRF + recovery-code wraps, server outer wrap, no server recovery) (#757) (#867)
- Signer port: sign by key reference via Turnkey delegated access or Secrets-held session keys, guarded and audit-chained (#761) (#865)
- adapter-telegram + module-telegram: verified bot webhook, account linking, rate-limited messages, signed action buttons and a notifications channel (#764) (#864)
- allowlists, caps, required simulation, hard denies and a kill switch for value-moving actions (#763) (#862)
- Linear adapter (
cratefield-adapter-linear) with comment and inbound status webhook (#559, part 2) (#850) - link EVM and Solana wallets to a signed-in account via SIWE/SIWS (plus a push-protection fix) (#838)
Other
- streaming completions (text, reasoning, tool-call and usage deltas) with idle/total timeouts and cancel-on-drop (#869)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- the
Trackerport over the Linear GraphQL API — file, status, comment and theLinear-Signatureinbound status webhook (#559, part 2)
- the
Added
- core Speech port — transcription and streamed synthesis, with Workers AI and OpenAI-compatible adapters (#861) (#868)
Speechover the OpenAI audio wire (issue #861):OpenAiCompatibleSpeechtranscribes throughaudio/transcriptionsand synthesizes throughaudio/speechat any base URL, under the same key andNotConfiguredrules as the chat adapter, with the port's limits enforced before any request.- TextModel image inputs (issue #628): a
Prompt's imageParts serialise into the request'scontentarray ({"type":"image_url","image_url":{"url":"data:<media-type>;base64,…"}}), text-only messages keep their plain-string content, image input is opted into withOpenAiCompatible::with_images()(Capability::Images, off by default), an image prompt without it is refused withUnsupportedbefore any request, andPrompt::check_imagesbounds are enforced locally first.
Other
- streaming completions (text, reasoning, tool-call and usage deltas) with idle/total timeouts and cancel-on-drop (#869)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- updated the following local packages: cratefield-core
Added
- First release, 0.1.0: the
TelegramBotport over the Telegram Bot API, through theHttpClientandClockports. It sends, edits and deletes messages and answers callback queries under global and per-chat rate budgets, parses typed inbound updates, and verifies the secret-token webhook. The bot token never rides a log line (#764).
Dependency updates only.
Other
- the Turnkey provider for the
KeySignerport (#761): passkey-rooted sub-organizations with a delegated-access user, policy-scoped signing by key reference, and DENY-policy kill switches
- the Turnkey provider for the
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Added
- core Speech port — transcription and streamed synthesis, with Workers AI and OpenAI-compatible adapters (#861) (#868)
Speechover the Workers AI binding (issue #861):WorkersAiSpeechtranscribes with Deepgram Nova-3 (the default) or Whisper and synthesizes with Deepgram Aura, behind aSpeechRunnerseam (SpeechBindingin production). Its default audio ceiling is lowered toWORKERS_AI_MAX_AUDIO_BYTES, because the binding takes the clip as a JSON number array.
Dependency updates only.
Other
- fz doctor: fail on module SQL a venture's dependencies ship but no module declares (migration-not-declared) (#872)
Dependency updates only.
Added
- core SSE response helper and AI SDK UI message stream encoder (#860) (#871)
- core Speech port — transcription and streamed synthesis, with Workers AI and OpenAI-compatible adapters (#861) (#868)
- core HttpClient outbound budgets — per-upstream token buckets, Retry-After backoff, daily quota alerts (#765) (#858)
- core report per-provider mailer status in /__health (#793) (#845)
- Chunk-and-reassemble completion (issue #847).
split_text_chunkssplits a long document into chunks of at mostmax_charschars on paragraph boundaries, never inside a fenced code block (an oversized fence is the one atomic, oversized chunk), and the round trip is byte-exact;reassemble_text_chunksstitches the pieces back in order;TextModelChunkedExt::complete_chunkedruns the split → per-chunkTextModel::complete→ reassemble loop over anyTextModel, so a long rewrite no longer has to fit inside oneHttpPolicyresponse timeout. For generation-shaped jobs preferTextModel::stream(issue #859) — chunking buys its bound with one round trip per chunk. - A
Speechport (issue #861, ADR 0029).transcribe(audio in, aTranscriptwith optional word timings out) andsynthesize(text in, a streamedSynthesisout), plusvoices,capabilitiesandlimits. Limits are checked locally before any network call bycheck_transcribe/check_synthesize, which refuse withSpeechError::LimitExceeded;wav_durationreads a WAV header's length without a codec.NotConfiguredSpeechis the standing placeholder for an unwired port. - The facade gains a
sealedfeature (issue #757). It re-exports the newcratefield-module-sealedascratefield::sealed: the server half of client-side sealed blobs. It stores opaque ciphertext under a server outer wrap, erases by crypto-shredding, and has no server-side recovery path;@cratefield/sealedis the browser client. Nothing incratefield-corechanges. - The facade gains
telegramandtelegram-eventsfeatures (issue #764). They re-export the newcratefield-adapter-telegramascratefield::telegramandcratefield-module-telegramascratefield::telegram_events: the Telegram Bot API adapter, and the verified webhook, account linking and consent buttons that never move value without a passkey. Nothing incratefield-corechanges. - The facade gains a
guardrailsfeature (issue #763). It re-exports the newcratefield-module-guardrailsascratefield::guardrails: the policy engine every automated value-moving action must pass, with hard denies, allowlists, required simulation, micro-USD caps, a kill switch and audit. It denies by default and fails closed. Nothing incratefield-corechanges. Mailer::providers()names the providers behind the port (issue #793). The newMailProvider { name, configured, healthy }reports a name and two verdicts and never a credential — a health report that leaked an API key would be a secret published on an unauthenticated endpoint./__healthgains a"mailers"array beside the unchanged"mailer"key; the two answer different questions (is the port wired, does the adapter hold its key), so a Resend with no API key readsconfiguredandconfigured: false.healthyisNone— and the JSON key is then omitted — for an adapter with no probe, because "unknown" is not "unhealthy". The method has a default, so every existing adapter compiles unchanged and still lists itself.
Fixed
- auth a webview can press the magic-link confirm button; themeable hosted pages and mail; friendly validation (#840) (#841)
- A handler's
Referrer-Policy: same-originsurvives the no-store stamp (issue #840)./v1/*and token-carrying responses still getno-referrer, except when the handler itself answered withsame-origin, which also sends nothing cross-site. Underno-referrera browser sendsOrigin: nullon a page's own form POST, which a login-CSRF guard must refuse from clients that send noSec-Fetch-Site(webviews, older Safari). Any other policy a handler sets is still overwritten.
Other
- streaming completions (text, reasoning, tool-call and usage deltas) with idle/total timeouts and cancel-on-drop (#869)
- module-sealed + @cratefield/sealed: zero-knowledge sealed blobs (passkey PRF + recovery-code wraps, server outer wrap, no server recovery) (#757) (#867)
- adapter-telegram + module-telegram: verified bot webhook, account linking, rate-limited messages, signed action buttons and a notifications channel (#764) (#864)
- allowlists, caps, required simulation, hard denies and a kill switch for value-moving actions (#763) (#862)
Dependency updates only.
Fixed
Added
MailTheme::header_bg/header_textanddisplay_font(issue #840), all opt-in: a solid header band behind the logo row, joined to the card (inline, so Gmail keeps it), and a heading font stack. Both are sanitised like the other colours and fonts; unset, every mail renders as before.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- ADR 0030: the mail-theme record takes the number it was sharing (#875)
Other
- updated the following local packages: cratefield-core
Added
- First release, 0.1.0: the policy engine every automated value-moving action must pass. It checks hard denies, recipient and contract allowlists, required simulation and micro-USD caps, and it has a kill switch and an audit trail. It denies by default and fails closed (#763).
Other
Added
- a
Channeltrait for extra delivery channels a venture registers with.channel(..), such as Telegram: one outbox row per registered channel on thenotifications.channeltopic, with the push adapters' error shapes (#764)
- a
Dependency updates only.
Dependency updates only.
Other
- updated the following local packages: cratefield-core
Added
- First release, 0.1.0: the server half of client-side sealed blobs. It stores the ciphertext the
@cratefield/sealedclient produces under a server outer wrap, serves it back byte-identical, erases it by crypto-shredding, and has no server-side recovery path (#757).
Other
- updated the following local packages: cratefield-core
Added
- First release, 0.1.0: Telegram in a venture, mounted at
/v1/telegram. It verifies the secret-token webhook, links Telegram accounts with one-time codes, and sends consent buttons that can deny anything and approve anything harmless, but only arm a value-moving action until the owner confirms it with a passkey. With thenotificationsfeature it is also amodule-notificationschannel (#764).
Dependency updates only.
Other
- ADR 0030: the mail-theme record takes the number it was sharing (#875)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- streaming completions (text, reasoning, tool-call and usage deltas) with idle/total timeouts and cancel-on-drop (#869)
Other
- streaming completions (text, reasoning, tool-call and usage deltas) with idle/total timeouts and cancel-on-drop (#869)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Added
- core Speech port — transcription and streamed synthesis, with Workers AI and OpenAI-compatible adapters (#861) (#868)
- core HttpClient outbound budgets — per-upstream token buckets, Retry-After backoff, daily quota alerts (#765) (#858)
Speechport conformance (issue #861):speech_conformanceandspeech_conformance_not_configured, with the shared fixture constants, behind theport-conformancefeature.
Dependency updates only.
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Fixed
- thirteen error-handling defects, plus make the guard-script tests survive a non-executable checkout (#828)
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Fixed
- thirteen error-handling defects, plus make the guard-script tests survive a non-executable checkout (#828)
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Other
- update Cargo.lock dependencies
Other
- update Cargo.lock dependencies
Other
- charge amounts, currency exponents and ledger entry types (#832)
Fixed
- thirteen error-handling defects, plus make the guard-script tests survive a non-executable checkout (#828)
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Added
- A provider-neutral billing lifecycle, in
billing(issue #593, ADR 0025). New pure types and functions —LifecycleEventand itsLifecycleKind,Status,SubscriptionState,LifecyclePolicy,transitionandgives_access— that map a Stripe or RevenueCat webhook onto a state and answer whether it grants access, with no I/O and no vendor payload parsing (that stays in the adapters, issues #600 and #601). Additive: no existing API changed andHARNESS_APIis untouched. - TextModel image inputs (issue #628):
Part(Text/Image),Turn::user_parts,Prompt::user_parts,Prompt::has_images,Prompt::check_images,Capability::Images,TextModelError::ImageLimit, theencode_image/encoded_image_lenhelpers, and theMAX_PROMPT_IMAGES/MAX_IMAGE_ENCODED_BYTES/MAX_PROMPT_IMAGE_ENCODED_BYTESbounds. The router andrun_tool_loopgateCapability::ImageslikeCapability::Tools. StatusOnly, a request marker asking for the status line alone. An implementation that honours it returns no body and no body-describing headers, because there is no body to describe — cheaper thanHEADwhere the endpoint is already known and only liveness is wanted. It rides as a request extension exactly asHttpPolicydoes and waives the body, not the ceilings; an implementation that does not read the extension answers the request like any other (#714).
Fixed
- thirteen error-handling defects, plus make the guard-script tests survive a non-executable checkout (#828)
Fixed
- thirteen error-handling defects, plus make the guard-script tests survive a non-executable checkout (#828)
Fixed
- close five input-validation gaps — an unescaped HTML sink, a javascript: URL, an unvalidated slug, an OAuth token sent to any host, and an unclamped page size (#826)
GET /v1/notifications?limit=0no longer returns an empty inbox. The page size is clamped to1..=INBOX_PAGE_MAX(the idiommodule-orgsandmodule-crmalready use) instead of only capped from above, so a zero limit is the default page rather than a page that looks full and hands back a next cursor for a page that cannot exist. A limit above the ceiling still clamps toINBOX_PAGE_MAX.
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Fixed
- close eight concurrency races across the pool cache, auth caches, realtime rooms, waitlist confirms and tracker adapters (#823)
Other
- image inputs (Part::Image) for the Anthropic and OpenAI-compatible adapters (#745)
Added
- Image input (issue #628): a
Turn::user_partsmessage is sent as the Messages API content-block array, text and inline base64 images in order.Anthropic::supportsnow reportsCapability::Images, and an image prompt over the port's bounds is refused (TextModelError::ImageLimit) before any network call.
Added
- adapter-owlpost sending domains — create, list, get, verify, delete (#681) (#797)
- adapter-owlpost suppressions and topic naming (#669) (#795)
- adapter-owlpost typed webhook events and a verify-then-parse entry point (#668) (#796)
- adapter-owlpost inbound messages — list/search, held, get, raw, reply, release (#682) (#798)
Other
- accept a set of expected hostnames (apex + www) (#802)
Other
- drop the stale release-plz hold comment (cratefield-tables promotion already done) (#722)
Other
- document the deferred confirmation mail, and correct every doc that still promises the join-time 503 (#806)
Other
- serve the CF08 provider protocol from a harness deployment, and apply the account provider last (#792)
Added
- (provider server)
Privacy::serve_provider, so a deployment can answer the same signed protocol it calls out on:POST /v1/privacy/provider/{export,erase/plan,erase/apply}over this composition's own declarations, with the HMAC as the authorisation rather thanADMIN_TOKEN, and no routes at all where it was not opted in (#656). HttpProvider::account(), marking the provider that holds the identity so it is applied last — unmarked providers in registration order, then the marked ones — in all three loops (#656).
Other
- runtime-cloudflare HttpClient: cap the response body while streaming, and don't follow redirects (#809)
- Actor port: per-key serialized state with transactional storage and alarms, on Durable Objects (#583) (#743)
- Blob port: streamed reads and writes, multipart uploads and listing for objects above MAX_BLOB_BYTES (#586) (#741)
Security
- The response body is read as a stream under the
HttpPolicycap, so an upstream that never declares acontent-lengthis refused at the chunk that crosses the cap rather than buffered first. Reading stops there and drops the platform's handle on the fetch, so an endless body costs one chunk past the cap instead of the isolate's memory. The platform offers no stream at all for a null-body status (204/205/304, or the reply to aHEAD), which is read as an empty body rather than a failed send, so the cap does not cost those replies the buffered read used to answer (#714). - Redirects are answered, not taken: the transport request asks for
redirect: "manual", so no upstream can move the exchange to another host or down tohttpafter the destination was vetted (#714).
Added
StatusOnlyrequest marker honoured: a request carrying it is answered from the status line alone, its body never read, and its body-describing headers (Content-Length,Content-Encoding,Transfer-Encoding) dropped, so a liveness probe of a large resource does not fail on a length it never asked for (#714).
Other
- Actor port: per-key serialized state with transactional storage and alarms, on Durable Objects (#583) (#743)
- image inputs (Part::Image) for the Anthropic and OpenAI-compatible adapters (#745)
- Blob port: streamed reads and writes, multipart uploads and listing for objects above MAX_BLOB_BYTES (#586) (#741)
Added
- TextModel image inputs (issue #628): the
text_model_image_bounds_conformanceport suite, and aFakeTextModelthat answers image prompts and refuses an over-limit one before recording it.
Other
- schema-validated structured output (complete_json / complete_as) (#739)
Other
- one branded instance per app; cratefield-auth-* crates; Owlpost mail (#778)
Other
- Stripe customer portal sessions and subscription lookup (#589) (#740)
- schema-validated structured output (complete_json / complete_as) (#739)
- Venture CORS: accept browser-extension origins (chrome-extension, moz-extension, safari-web-extension) (#737)
- Inbound mail: a verify-then-parse source in core, a Resend inbound adapter, and ADR 0028 for channels (#563) (#734)
Other
- Supabase import: plan.json, bare
fz import supabasedry run,--apply --plandrift check and target extension preflight (#754) - Supabase import: record per-item dispositions (covered/waived) in a file and merge them into the report (#752)
- import-supabase keep the crate version out of the fixture-report snapshot (#786)
- Supabase inspect: drop managed-schema policies, route storage policies to their buckets, flag RLS-on/no-policy tables (#751)
- Supabase import: plan.json, bare
Other
- one branded instance per app; cratefield-auth-* crates; Owlpost mail (#778)
Other
- Venture CORS: accept browser-extension origins (chrome-extension, moz-extension, safari-web-extension) (#737)
Added
- tables-api a composite key gets its single-row routes at
/{table}/__by(#153) (#475) - tables-api
?sort=on the page route and in a batch read (#383) - tables-api several declared reads in one request (#381)
- tables order a page by a declared column (#380)
- tables filter a page, and fix the nullable column it uncovered (#378)
- tables-api serve the writes the surface already publishes (#374)
- a venture publishes the tables it declares (#372)
- tables-api writing a declared table, with ownership enforced (#369)
Fixed
- tables-api publish cratefield-tables-api so the facade can package (#787)
- core ERRORS.md covers every crate's problem slugs, and a duplicate slug fails CI (#419) (#552)
- tables-api
tenant-membersfails closed where membership cannot be checked (#385) (#424) - the manifest's vocabularies are checked against the types they mirror (#404)
- tables-api a conflict is the engine's phrase, not the word "unique" (#393)
- a subject column must be able to hold a caller's id (#391)
- tables a json column is not filterable, in either path (#390)
- tables a filter for a null asks IS NULL, not
= NULL(#389) - tables-api a composite-key table publishes only the routes it has (#387) (#388)
- tables-api the cursor the server hands back is one it accepts (#379)
Other
- Scheduled work runs on a cooperative per-module budget, with a budget-aware Outbox drain (#537) (#543)
- /__surface publishes an output schema for table reads, so public-read rows can be typed (#517)
- Close four existence oracles: signup timing, owner-table conflicts, passkey issuance, Stripe signature compare (#487)
- adr a composite key is addressed by query, not by path (#387) (#422)
- two names that point at nothing (#410)
- tables-api a declared table's redaction and anonymisation are real (#397)
tenant-membersadmits any verified caller, and say so (#385) (#386)- a writable declared table does not make a venture demand a captcha (#377)
- a declared table's privacy block reaches export and erasure (#375)
- The generated module serves the tables it declares (#370)
- The routes, so a declared table is actually reachable (#368)
- Reading a declared table, with the access level applied (#366)
- The decision about who reaches whose rows (#364)
- tables-api a composite key gets its single-row routes at
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Added
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Added
Changed
- Breaking (found by cargo-semver-checks):
ports::text_model::Turnis now#[non_exhaustive]and no longer derivesEq, so it is built withTurn::user,Turn::assistant,Turn::assistant_tool_callsorTurn::tool_resultsrather than a struct literal;TextModelErroris now#[non_exhaustive], so amatchon it outside core needs a wildcard arm (#705).
- Breaking (found by cargo-semver-checks):
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Added
- mail-templates branded mail in each venture's own style for every module that sends mail (#715) (#716)
MailTheme(brand name, wordmark, hosted logo and alt text, light and darkPalettes, font stacks, radii, footer lines, contact), resolved from the venture's composition, itsMAIL_THEMEconfig, or its coreBrand; andMailTheme::cratefield(), Cratefield's own theme.Message, a builder for one mail (heading, paragraphs, facts, primary button, fallback link, code, notes, recipient and reason, footer links,langanddir) rendering an email-client-safe HTML part with a dark variant and a plain-text twin, every value escaped (#715).
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Added
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712). - The confirmation and welcome mails render through
cratefield-mail-templatesin the venture's theme (layout, dark variant, preheader, text twin), replacing the askama templates; subjects are unchanged and the unsubscribe link moves to the footer.themed_templates(&theme)composes the venture's ownMailTheme;default_templates()uses the theme resolved from the venture'sBrandandMAIL_THEME(#715).
- Breaking: requires
Added
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712). - The notification email renders through the template registry as
notifications/email, in the venture's theme viacratefield-mail-templates, so a venture can restyle or reword it.default_templates()andthemed_templates(&theme)are new; subject selection,lang/dir,Content-Languageand the one-click unsubscribe headers are unchanged (#715).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Added
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712). - The confirmation and "you're in" mails render through
cratefield-mail-templatesin the venture's theme: a 600px email-client-safe layout with a dark variant, a preheader and a plain-text twin, replacing the askama templates. Subjects are unchanged; the confirmation gains an "ignore this if you didn't join" note.themed_templates(&theme)composes the venture's ownMailTheme;default_templates()renders in the theme resolved from the venture's coreBrandand itsMAIL_THEMEconfig, which also reaches override templates asthemein their data (#715).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
- Breaking: requires
Changed
- Breaking: requires
cratefield-core0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).
Other
- updated the following local packages: cratefield-core
- Breaking: requires
Added
- webhooks outbound webhook delivery module with per-endpoint secrets, retries, dead letters and replay (#536) (#544)
- oauth-client reusable OAuth 2.0 client crate, with module-linkedin ported onto it (#531) (#547)
- adapter-anthropic the first TextModel adapter, over the HttpClient port (#430) (#481)
- changelog a module that mirrors a repository's releases and serves them (#418)
- manifest a declared table becomes a module the venture composes (#153) (#358)
Other
- App JWTs, cached installation tokens, and a named GitHub webhook scheme (#623) (#637)
- per-account third-party OAuth connections with sealed tokens, refresh and revoke (#624) (#638)
- OAuth 2.0 device authorization grant (RFC 8628) issuing a venture-defined credential (#587) (#633)
- CustomHostnames port in core, with a Cloudflare for SaaS adapter (#590) (#630)
- a Mailer over the Owlpost API (#591) (#629)
- comment op, inbound status webhooks, Freshdesk destination and the Jira Cloud adapter (#559, part 1) (#582)
- OpenAI-compatible adapter, cached-token usage on every completion, shared TextModel conformance suite (#560) (#567)
- cratefield-core 0.6.0 and every publishable dependent (#558) (#565)
- Drop the Cargo.toml comments that still say published crates are
publish = false(#495) (#548) - Remove the space runs from the Signer readiness message, and make the facade crate doc match NOT_LIBRARIES (#527)
- Stop holding back cratefield-tables in release-plz.toml now that it is on crates.io (#513)
- Docs accuracy: free-tier module copy, facade feature table, privacy erasure docs, cooldown declaration, removal consent flag (#509)
- Classifier port, with your own TypeSafe key, Workers AI, or the LLM you already have (#501)
- adapter-github-issues and adapter-webhook-tracker: the first two Tracker adapters (#482)
- Release round: bump the 23 core dependents so their next publish requires core ^0.5 (#496)
- anonymous usage telemetry any venture can compose, opt-out (#471)
- The generated module serves the tables it declares (#370)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- report metered usage to Stripe Billing Meters, idempotently (#662)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- Route policy: let one module declare a signature verifier per webhook route (#595) (#632)
- Production readiness fails when a module declares RateLimiter and none is mounted; a missing Workers limiter binding fails closed (#562) (#569)
- Verify the cratefield-core 0.6.0 release round (#558) and fix a stale client-ts comment in the CLI manifest (#566)
Added
- core breaking add Destination::Colonizer { repo } and RoutingTracker::colonizer (#676) (#687)
- core breaking name problem
typeURIs under the venture's own base (#557) (#581) Paymentscarries a Merchant of Record (ADR 0027). New optional methods, each with a default, so every existing adapter compiles unchanged andHARNESS_APIstays 1:verify_webhook_request(&HeaderMap, body)for providers that sign over several headers (Standard Webhooks; the default readsStripe-Signature);create_portal_sessionwithPortalSessionRequest/PortalSessionin issue #589's shape; andget_dispute,list_disputesandclose_disputewithDispute,DisputeStatus,DisputePhase,DisputeListRequestandDisputePagein issue #602's shape.DisputeStatus::phase()folds a provider status intoOpen/Won/Lost/Closed;Dispute::event_key()is theInboxkey for one transition. The defaults answerPaymentsError::Unsupported. (#690)Tracker::commentandTicketComment: add a note (optionally linking a URL) to an existing ticket, so a duplicate report links into the ticket it duplicates. The default impl refuses withTrackerError::Rejectednaming the tracker, so existing adapters compile unchanged;RoutingTrackerforwards it by destination. (#559)- Inbound status webhooks: the
StatusWebhooktrait,StatusUpdate,InboundStatusErrorandreceive_status, which verifies a delivery with core'sWebhookVerifierbefore the adapter ever parses it. (#559) Destination::Freshdesk { domain }andRoutingTracker::freshdesk; no adapter ships for it yet. (#559)Destination::Colonizer { repo }andRoutingTracker::colonizer; no adapter ships for it yet. (#676)TicketStateis nowSerialize/Deserialize(snake case), so a state can cross the inbound webhook wire. (#559)
Other
- Blob port: presigned GET and PUT URLs for R2 through the S3 API (SigV4) (#622) (#663)
- report metered usage to Stripe Billing Meters, idempotently (#662)
- App JWTs, cached installation tokens, and a named GitHub webhook scheme (#623) (#637)
- Webhook verification: Vercel (HMAC-SHA1) and GitLab (shared-token) schemes (#636)
- Stream request and response bodies for routes a module declares (#585) (#635)
- Usage metering: per-subject, per-period counters with an atomic check-and-increment (#588) (#634)
- CustomHostnames port in core, with a Cloudflare for SaaS adapter (#590) (#630)
- ADR 0025: provider-neutral billing lifecycle, entitlements and revenue ledger, fed by Stripe and RevenueCat (#592) (#631)
- Route policy: let one module declare a signature verifier per webhook route (#595) (#632)
- comment op, inbound status webhooks, Freshdesk destination and the Jira Cloud adapter (#559, part 1) (#582)
- VectorIndex and Embedder ports, with Cloudflare Vectorize and exact in-process adapters (#561) (#568)
- OpenAI-compatible adapter, cached-token usage on every completion, shared TextModel conformance suite (#560) (#567)
- Production readiness fails when a module declares RateLimiter and none is mounted; a missing Workers limiter binding fails closed (#562) (#569)
Changed
- Breaking — problem
typeURIs are named under the serving venture's own base.Problem::type_urinow takes the venture's base as its argument, so the next release is 0.7.0 (a breaking change is a minor bump under 0.x):typeis<public_url>/problems/<slug>— derived from the venture'spublic_url, overridable with the newVenture::problem_base(..)— andabout:blank(RFC 9457 §4.2.1) for a venture with no public URL, instead of one hard-codedhttps://factory0.ventures/problems/base for every venture.Problem::into_responserenders the context-freeabout:blankand stores the problem in the response extensions; the harness's outermost layer re-renders the body under the venture's base, so every path that serves a problem — module handlers, the tenant and readiness gates, rejections, 429s — names the venture it served for; the runtimes' pre-router refusals (native421, Worker413and unresolved-limiter503) name it through the newProblem::into_response_with_base. Clients must match on the slug — the part after/problems/,auth/…namespaces included — never on the full URI. The slug list is unchanged (docs/ERRORS.md). (#557)
A breaking change is pending here:
Destinationis an exhaustive enum and gainedFreshdeskandColonizer, so amatchover it no longer compiles unchanged; the next release of core is therefore 0.7.0, not 0.6.1.Destination::Jira { site }is documented as the bare hostname (acme.atlassian.net), not the hostname prefix: the newcratefield-adapter-jirarefuses anything else, so the Basic credential cannot be sent to another host. (#559)
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Changed
- breaking The confirmation mail is deferred: the entry lands on the request path and
POST /v1/waitlistnow always answers202 {"ok":true}. Upgrading from 0.2.0 removes the503 mail-not-configureda join used to return when no mailer was configured — with no mailer the entry is recorded aspendingand no mail is sent, and theNotConfiguredis only logged. The answer is deliberately identical for every row state so it leaks nothing about the address (#713).
- breaking The confirmation mail is deferred: the entry lands on the request path and
Dependency updates only.
Dependency updates only.
Dependency updates only.
Other
- Blob port: presigned GET and PUT URLs for R2 through the S3 API (SigV4) (#622) (#663)
- Stream request and response bodies for routes a module declares (#585) (#635)
- CustomHostnames port in core, with a Cloudflare for SaaS adapter (#590) (#630)
- VectorIndex and Embedder ports, with Cloudflare Vectorize and exact in-process adapters (#561) (#568)
- Production readiness fails when a module declares RateLimiter and none is mounted; a missing Workers limiter binding fails closed (#562) (#569)
Dependency updates only.
Added
Other
- Blob port: presigned GET and PUT URLs for R2 through the S3 API (SigV4) (#622) (#663)
- Stream request and response bodies for routes a module declares (#585) (#635)
- Usage metering: per-subject, per-period counters with an atomic check-and-increment (#588) (#634)
- CustomHostnames port in core, with a Cloudflare for SaaS adapter (#590) (#630)
- comment op, inbound status webhooks, Freshdesk destination and the Jira Cloud adapter (#559, part 1) (#582)
- VectorIndex and Embedder ports, with Cloudflare Vectorize and exact in-process adapters (#561) (#568)
- OpenAI-compatible adapter, cached-token usage on every completion, shared TextModel conformance suite (#560) (#567)
September 2026
cratefield-core 0.6.0
crates.ioA breaking release:
Portis an exhaustive enum and gainedTextModel,Tracker,ClassifierandAuthsince 0.5.0, so amatchover it no longer compiles unchanged. Every published dependent is re-released against^0.6in the same round, so the crates.io set resolves on one core again (#462, #464, #558).Added
webhook_signature: a generic HMAC-SHA256 webhook verifier (WebhookVerifier) with pluggable schemes (Svix,StripeStyle,ProviderScheme), plusSignatureVerificationand a defaultedModule::signature_verification(), so aRoutePolicy::Signatureroute can be proved by awebhook_signaturescheme instead of thePaymentsport; the boot gate then checks the module's secret key (webhook_secret_readiness) in place of thePaymentsleg. (#533)
cratefield-core 0.4.0
crates.ioA major bump because it has to be:
cargo semver-checksagainst the published 0.3.1 reports 11 major and 0 minor failures. Under 0.x that is 0.4.0. Every item under Changed below is one the tool found, not one read off the commit log.Note also that 0.3.0 and 0.3.1 were published without entries here; this one covers the surface as it stands against 0.3.1.
Changed
Database::batchis gone.batch_atomicreplaces it and has no default implementation, so everyDatabasemust provide it — the point being that a batch is all-or-nothing by contract rather than by hope. (#126)- Structs that could be built from a literal no longer can, having gained public fields:
ModuleContext(unprotected_writes_accepted,personal_data),Ports(realtime,tenants),HarnessConfig(harness_secret_revoked,harness_venture),Action(policy) andNotification(icon,url,ttl,badge,silent,loc). MessageandSqlMigrationare#[non_exhaustive], as are theKidandSignerErrorenums — so literals and exhaustive matches on them need a rest pattern. (#255)PortgainedRealtime, which shifted the discriminants ofHttpClient(9 → 10),Clock(10 → 11),IdGen(11 → 12) andDefer(12 → 13). Code casting aPortwithas isizegets a different number.PushError::Transientchanged shape, andSignerError/Kidno longer have well-defined discriminants because they now carry data.- New variants on exhaustive enums:
BlobError::TooLarge,HttpError::{ResponseTooLarge, DeadlineExceeded, BlockedDestination},SignatureError::{WrongScope, RevokedKey}. Kidno longer derivesCopy, andHmacSigneris no longerUnwindSafeorRefUnwindSafe.
Added
The public surface went from 227 items to 362. The larger pieces:
Outbox— persist-before-defer delivery, so queued work survives the request that created it, with asubjectcolumn that keeps a queued row inside export and erasure. (#128, #266)- The personal-data catalogue —
PersonalDataSet,PersonalDataCatalog,Disposition,CatalogEntry: every module declares what it holds about a person, and a table erasure cannot reach is published as its own fact rather than as "not personal data". (#244, #272, #274, #291) - Tenancy —
Tenant,TenantId,TenantConnand tenant resolution. (#32) - Sidecar boundaries — events cross inbound only, identity and contract per response rather than at cold start, and a sidecar's tables are visible to the collision check. (#61, #62, #66)
- Boot-time reconciliation, per module and per tenant. (#30)
RealtimeandBlobports, andModule::well_knownrouting.
cratefield-core 0.2.0
Added
Module::well_known(): a module can serve routes at/.well-knownat the root (OIDCopenid-configuration,jwks.json), where discovery agents look for them.Harness::buildfails naming every module when two both provide one; nothing but/.well-knownis ever mounted at the root. (#46)cratefield_core::http::Form: anapplication/x-www-form-urlencodedextractor re-exported besideJson, with the same 64 KiB body limit and the same problem+json rejections (400 validation-failed,413 request-too-large) — for cross-siteform_postcallbacks such as Sign in with Apple. axum'sformfeature is now enabled in the workspace dependency. (#46)- Conformance kit (
cratefield-testing): a module with a well-known router is checked to mount at the root under/.well-knownand never under/v1. (#46)