The constraint was not “make a model write a quote”
A single prompt can produce a sentence. It cannot establish whether the system model is ready, keep an interface responsive, distinguish a generated line from a historical quotation, prevent a near-duplicate from entering a library, or leave the product useful when inference fails. Those surrounding decisions are the feature.
RiseHush has no inference backend. On supported Apple Intelligence devices, the app sends a bounded prompt to Apple’s on-device system language model and stores an accepted result in local SwiftData. The product-facing intelligence page explains what a person sees; this article documents the implementation path and its limits. Apple’s own availability API remains the authority for whether the model can run now.
“Reproducible” here means another engineer can repeat the readiness matrix, rejection fixtures, timeout paths, and persistence checks. It does not mean a nondeterministic language model will return the same prose bit for bit. This page reports inspected source architecture, not fresh physical-device quality metrics; no benchmark result is inferred from a test script.
- Inference: Apple’s system language model, on device.
- Output contract: A guided Swift type, then deterministic validation.
- Storage: Local SwiftData rows marked as generated.
- Network path: No RiseHush generation server or third-party model.
From prompt to library: the production path
This is the architecture behind RiseHush’s on-device quote generator as inspected in the current app source. It documents the gates, failure paths, and checks a developer can reproduce; it is not a model benchmark or a claim that every draft is good.
The ordering is deliberate. Cheap, explainable checks run before more inference; no write occurs until every required gate has accepted the candidate. A streamed answer is provisional interface text, not a saved quote.
Prove readiness
The service checks the system model’s availability and the requested locale before it creates a session. Device eligibility, Apple Intelligence state, model-asset readiness, and language support are separate outcomes.
Constrain the draft
A @Generable Swift type asks for one original sentence, normally 10–16 words and never more than 18, with no attribution, markdown, hashtags, emoji, or wrapping quotation marks.
Stream off the main actor
A fresh LanguageModelSession is prewarmed for the request. Partial structured snapshots can update the interface while the Foundation Models loop remains off the main actor.
Reject obvious failures
Before any model-based judging, a deterministic gate checks sentence and word limits, language agreement, banned fragments, wrapping punctuation, and multilingual cliché patterns.
Test novelty and quality
When comparison embeddings are available, survivors face a semantic near-duplicate check, then a separate guided judge and distinctiveness score. A streamed draft that misses a required threshold is discarded rather than silently persisted.
Persist the survivor
Metadata is computed away from the main actor. SwiftData insertion returns to the main actor, labels the line as generated and not public-domain, and rolls back transient inserts if saving fails.
Reuse local state
The app and system surfaces consume the stored quote. Widgets read persisted data; they do not wake the language model inside an extension timeline.
Guided output narrows shape; code still owns policy
The draft is a Swift type marked @Generable. Its guide asks for one original sentence, normally 10–16 words with a hard prompt maximum of 18, and prohibits attribution, wrapping quotation marks, hashtags, emoji, markdown, and line breaks. The production options use temperature 0.7 and a 40-token ceiling: enough room for the structured wrapper and short sentence, without inviting paragraph-length output.
This does not make validation optional. Apple describes guided generation as a way to produce structured Swift data, not a guarantee that the content meets every product rule. RiseHush therefore treats the model’s typed value as an untrusted draft. The abridged sketch below preserves the production ordering and thresholds while omitting app-specific prompt and persistence detail.
@Generable
private struct GeneratedQuoteDraft {
@Guide(description: "One original sentence; 10–16 words; no attribution")
var text: String
}
guard availability(locale: locale) == .available else {
throw GenerationError.unavailable
}
let stream = session.streamResponse(
to: prompt,
generating: GeneratedQuoteDraft.self,
options: generationOptions
)
for try await snapshot in stream {
yield(snapshot.content.text) // interface update
}
guard deterministicGate.passes(text, locale: locale),
await noveltyGate.isNearDuplicate(text) == false,
await judge.score(text).overall >= 6,
distinctiveness.score(text).overall >= 5
else {
throw GenerationError.noCandidate
}
return try persistAsGeneratedQuote(text)This is explanatory code, not a drop-in package. It intentionally omits app-private prompt construction, error mapping, and SwiftData model definitions.
Why a second pass still was not enough
The first rejection layer is deterministic: empty output, banned prompt residue, wrapping quotes, word and sentence limits, language disagreement, and multilingual cliché fixtures. A local Core ML taste filter can add a learned signal for English, German, Spanish, French, Italian, and Portuguese; it is deliberately skipped rather than misapplied outside those calibrated locales.
Next, when comparison embeddings are available, a semantic novelty gate compares the candidate with a bounded local catalog and rejects near-duplicates at a cosine-similarity threshold of 0.90. If the catalog is empty or an embedding cannot be produced, that layer passes through rather than claiming novelty was proved. A fresh Foundation Models session then scores overall quality, originality, and warmth. That judge is a separate session using the same system model—not an independent model and not a human review. If it is unavailable, refuses, or cannot produce structured output, a deterministic score provides a bounded fallback.
Finally, a distinctiveness score rewards concrete imagery, action, emotional specificity, and agency while penalizing formulae and recent negative anchors. Acceptance currently requires a judge score of at least 6 and distinctiveness of at least 5. These are product thresholds, not proof of global originality or safety.
| Concern | Implementation | Why it exists |
|---|---|---|
| Availability | Check model state and locale support before each generation path; record why readiness failed. | “Apple Intelligence capable” does not mean the model is ready now or supports the visitor’s active language. |
| Structure | Use @Generable and @Guide for the draft shape instead of parsing an invented JSON response. | The Swift type is the output contract, while deterministic code still owns product rules. |
| Concurrency | Keep model streaming and metadata work away from the main actor; cross back only for local model persistence. | The Foundation Models turn can take seconds, while SwiftData model objects remain actor-bound. |
| Quality | Layer deterministic rules, semantic novelty, a separate judge, and distinctiveness thresholds. | Guided generation narrows shape; it does not guarantee truth, originality, tone, or product quality. |
| Latency | Prewarm only on generation-capable foreground surfaces and apply finite budgets: 45 seconds in the interface, 20 for Siri, 120 for a background pool. | A user-facing request must not wait forever for assets, rate limits, or a slow model turn. |
| Persistence | Store accepted lines as local generated records, never as public-domain author quotations; roll back after a failed save. | Generated writing needs durable provenance and must never inherit a real person’s attribution. |
Keep the model turn away from the main actor
The public service returns SwiftData model objects, so its entry points remain main-actor-bound. The expensive Foundation Models response loop does not. Each request owns a fresh LanguageModelSession; streaming and metadata computation run away from the main actor, with small explicit hops for actor-bound prompt signals and persistence.
Streaming yields partial structured snapshots for the interface, then hands the final text through the same gate, novelty, judge, and distinctiveness bars as the pool path. A completed stream crosses actors by persistent identifier rather than moving a non-Sendable SwiftData model. The caller resolves that identifier on its own actor.
Only accepted text is inserted. The record is authored as RiseHush, marked source = .generated and isPublicDomain = false, tagged with its locale, and enriched with locally computed metadata. If saving fails, the transient inserts are deleted before the error returns.
Ground the concierge with three read-only tools
Ask RiseHush is not allowed to invent a person’s library state. Apple’s tool-calling API lets a session request narrow app functions and incorporate their returned data. The app exposes three bounded, read-only tools; none reaches a RiseHush server.
Tool arguments and output sizes are constrained. Saved-quote lookup returns at most eight results, catalog search at most five, and total tool output is capped. The saved-quotes tool can return recent matching items, but it does not accept a calendar range—so the product should not promise that the model can answer “what did I save last week?”
Catalog quote search
Searches the bundled quote catalog by mood, category, or theme. It does not ask the model to invent a source.
Saved quote lookup
Looks up the person’s own saved and favorite quotes in local storage.
Streak status
Reads the local inspiration streak so Ask RiseHush can answer a bounded personal question.
Failure behavior is part of the architecture
Availability is not a Boolean. A compatible device may still have Apple Intelligence disabled, model assets preparing, or a language the system model does not support. Runtime generation can also refuse, hit a guardrail, exceed context, be throttled, encounter a concurrent request, fail structured parsing, or time out.
RiseHush maps those cases to finite product behavior. Foreground generation has a 45-second budget, Siri 20 seconds, and background pool generation 120 seconds. The curated library remains the honest fallback; the app never stores placeholder prose as if a model succeeded.
| Signal | Behavior |
|---|---|
| Device not eligible or Apple Intelligence disabled | Generation is unavailable. The existing curated library remains usable without pretending a model response occurred. |
| Model assets not ready | The request reports a not-ready state. Once Apple’s model assets are present, inference itself does not require a RiseHush server. |
| Requested locale unsupported | A translation-capable path may fully gate an English draft and translate it locally where Apple’s Translation framework supports the pair; otherwise the app keeps the curated fallback. The translated text is checked for a nonempty result but does not repeat the full target-language gate, novelty, and judge stack. |
| Guardrail, refusal, rate limit, parsing, context, concurrency, or timeout error | The streaming path does not spin through an unbounded inline retry. It returns no generated candidate and lets the product fall back cleanly. |
| Draft misses a quality threshold | The finite pool path can try another draft; the live stream aborts rather than animating a second answer. Rejected text is not saved. |
| SwiftData save fails | The service removes its transient inserts and surfaces a persistence failure instead of leaving a half-saved quote. |
A reproducibility protocol, without invented results
The protocol below separates source inspection from live-device proof. Record hardware, OS build, locale, Apple Intelligence state, model readiness, prompt fixture, elapsed time, terminal branch, rejection reason, and persistence outcome for each run. Apple’s Foundation Models Instruments can expose prompt, tool, token, and latency behavior during a real session.
A machine-readable version is available as the Foundation Models evaluation protocol (JSON). It contains the matrix and field contract, not fabricated measurements. When a current physical-device run is approved, append its anonymized rows and publish aggregate acceptance, timeout, and latency values with the exact device and OS.
- Use compatible hardware with a supported OS. Test Apple Intelligence enabled and ready, disabled, and still downloading.
- Repeat with a supported locale and an unsupported locale; verify that the app distinguishes model support from general device eligibility.
- After model assets are ready, repeat in Airplane Mode and confirm that no RiseHush generation endpoint is required.
- Observe partial text while interacting with the interface; confirm that scrolling and controls remain responsive during the model turn.
- Feed fixtures that are empty, multi-sentence, too long, wrapped in quotes, in the wrong language, clichéd, or near-duplicates; none should become saved generated rows.
- Trigger judge rejection and a finite timeout; confirm that no rejected draft is persisted and the curated experience remains available.
- Force a local save failure in a test store; confirm that inserted models are rolled back.
- Exercise Siri with its shorter time budget and verify that widgets only read persisted data rather than starting generation in the extension.
What this architecture does not prove
A quality pipeline can make failure visible and reduce bad persistence. It cannot turn a small on-device language model into a historical source, prove that a sentence has never been written anywhere, or guarantee taste. Generated lines are therefore never attributed to historical authors and never enter the public-domain catalog.
Translation deserves a separate warning. For a locale unsupported directly by Foundation Models, the optional path fully gates an English draft and then uses Apple’s on-device Translation framework where the pair is available. The translated result is checked for a nonempty response and persisted with new metadata, but it does not currently repeat the full target-language gate, novelty, and judging sequence after translation. That path is a fallback, not evidence of equal direct-generation quality.
Model and OS updates can change availability, latency, refusal behavior, and output distribution. Apple recommends revisiting prompts and evaluation as Foundation Models changes. RiseHush’s test matrix must therefore be rerun after material platform updates rather than treating this page as permanent benchmark proof.
- The system model is not used as a source of historical quotation facts or author attribution.
- Structured output and a second model pass reduce failure modes; they do not prove that a line is profound, original in the global sense, or suitable for everyone.
- The semantic novelty layer passes through when its bounded catalog is empty or comparison embeddings are unavailable; it reduces known near-duplicates but does not certify global originality.
- Offline generation depends on compatible hardware, enabled Apple Intelligence, supported language behavior, and model assets already being ready.
- The optional learned Core ML taste filter is calibrated for English, German, Spanish, French, Italian, and Portuguese; other locales still receive the deterministic and model-based layers that support them.
- A locally translated fallback is not equivalent to direct target-language generation: the current translated result does not repeat every quality layer after translation.
- OS and model updates can change latency and output distribution, so the device matrix must be rerun after material platform changes.
- This page describes the current architecture, not a promise that every platform surface runs Foundation Models. Widgets intentionally consume persisted results.
Does RiseHush send quote-generation prompts to its own server?
No. On supported devices where the system model is available, the quote draft and quality passes run with Apple’s on-device frameworks. RiseHush has no inference endpoint for this path.
Does @Generable guarantee a good or original quote?
No. It constrains the shape of structured output. RiseHush still applies deterministic formatting and language rules, semantic near-duplicate detection when comparison embeddings are available, a separate judging session, distinctiveness scoring, and finite rejection behavior.
Can another developer reproduce the exact generated sentence?
Not reliably. Language-model output is nondeterministic and can change with model or OS updates. The reproducible unit is the readiness, fixture, gate, timeout, and persistence protocol—not identical prose.
Does every supported language receive the identical quality path?
No. Directly supported locales receive the common generation path, while the learned Core ML filter is calibrated for six languages. An optional locally translated fallback starts from a gated English draft but does not repeat every target-language quality layer after translation.
- Apple Developer Documentation — Foundation Models framework overview: direct access to Apple’s on-device language model
- Apple Developer Documentation — SystemLanguageModel availability and unavailable reasons
- Apple Developer Documentation — supporting languages and locales with Foundation Models
- Apple Developer Documentation — generating Swift data structures with guided generation
- Apple Developer Documentation — LanguageModelSession, responses, and streaming
- Apple Developer Documentation — expanding generation with tool calling
- Apple Developer Documentation — improving the safety of generative model output
- Apple Developer Documentation — analyzing Foundation Models runtime performance
- Apple Developer Documentation — Foundation Models framework updates
- Apple Developer Documentation — SwiftData
- Apple Developer Documentation — Translation framework
