Voice notebook
Record one bounded offline transcript and send a save request to the controller.
Documentation revision 1 · Contract reference API 54 · Installed readiness unknown
Preview offline card · Complete HTML interaction body · Machine-readable recipe
What runs where
- Explicit owner tap → 10-second microphone clip → installed Android on-device speech recognizer → editable notebook draft → one answer.
- No cloud fallback. The card can capture/transcribe without the controller, but saving the notebook requires the controller or another explicitly authorized storage integration.
Controller integration
- Controller persists returned transcript only after the owner answers. Do not store credentials or notebooks in example pages.
Only explicit decision-model/weather requests leave the phone; direct or relay transport still requires a running reachable phone.
Boundaries
- Not an always-listening notebook. It captures only a bounded clip on a deliberate tap.
- On-device recognition availability depends on Android and installed language resources. Empty transcript is not silence evidence.
Lifecycle
start
Configure card data, POST the generated HTML interaction; this does not automatically capture or poll.
update
Owner explicitly refreshes; controller stores approved data and posts a replacement card as needed, cancelling old pending cards.
pause
The Pause button suspends this card’s controls and suppresses results from a pending refresh. There is no background job in this starter; an in-flight capture may finish. Controller integrations must separately pause their jobs.
stop
The Stop button stops this card, suppresses late results, and requests controller shutdown through one response. Confirm/close the controller job and DELETE the interaction separately. Local stop is not proof that an external process stopped.
Failures and costs
- No offline recognizer: not_supported before recording. Unsupported language or capture error: show the actual error and let the owner retry.
- With return_audio=false, transcription failure fails the request; there is no audio fallback to upload.
- No Jev/Clef call. Local microphone and speech consume battery; keep clips bounded.
Complete synthetic contract examples
These fixtures demonstrate contracts. They are not observations from a phone. Replace image/resource IDs with returned authorized IDs. Load request.json as the complete body of POST /v1/interactions; it contains the full offline HTML.
record
{
"id": "record",
"request": {
"method": "POST",
"path": "/v1/mic/record",
"body": {
"duration_seconds": 10,
"transcribe": true,
"return_audio": false,
"language": "en-US",
"store": []
}
},
"response": {
"status": 200,
"body": {
"recorded_at": "2026-11-04T10:00:00Z",
"duration_seconds": 10,
"format": "m4a",
"sample_rate_hz": 44100,
"size_bytes": 81200,
"transcript": "Buy oats on the way home.",
"on_device": true
}
},
"evidence": "Synthetic contract fixture, not a device observation."
}
Extensions
- Add a separate optional controller summarizer after the owner approves the transcript.
- Use the separate owner-enabled wake-word system for hands-free collection; that is not silently enabled by this recipe.
Source evidence
- app/src/main/java/cc/bridgit/app/api/Endpoints.kt
- app/src/main/java/cc/bridgit/app/interact/CardRules.kt
- app/src/main/java/cc/bridgit/app/interact/CardActions.kt
- app/src/main/java/cc/bridgit/app/capability/Modules.kt
- app/src/main/java/cc/bridgit/app/planned/Transcriber.kt
- app/src/main/java/cc/bridgit/app/planned/TranscriptionResult.kt