15 KiB
Development Plan
Summary
This document is the current working plan for the OpenJibo hosted cloud.
The production lane is the .NET cloud in src/Jibo.Cloud/dotnet. The Node server remains the protocol oracle, capture harness, and fast reverse-engineering lab, but it is no longer the long-term hosted architecture.
Day-to-day feature sequencing lives in feature-backlog.md. This file tracks release shape, current code truth, evidence sources, and the boundary between 1.0.18 closeout work and 1.0.19 follow-up work.
Current Release Snapshot
- Current OpenJibo Cloud release constant:
1.0.18 - Source of truth: OpenJiboCloudBuildInfo.cs
- Spoken diagnostic:
Open Jibo Cloud version 1 dot 0 dot 18. - HTTP diagnostic:
/healthreturns the same version - Startup diagnostic: the API logs the same version on boot
- .NET target framework:
net10.0across the cloud projects and cloud test project
Release 1.0.18 is now in feature-hardening. Its main bug-fix theme is alarm and photo/gallery behavior on stock OS 1.9, with a few small feature slices added while the test loop is warm.
Latest Live Evidence
jibo test 24 was captured after the jibo test 23 alarm/photo fixes.
- Basic news remained live-proven from
jibo test 23;jibo test 24focused on alarm and photo/gallery regression. - Alarm replacement yes/no improved:
Yes.onclock/alarm_timer_changewas recognized locally. The persistent7:00 PMalarm from the previous session still caused repeated replacement prompts until menu cleanup. - Alarm still struggled around value-entry cleanup. Empty ASR under
clock/alarm_set_valuefell into generic Nimbus speech (I heard you.), andCLIENT_NLU intent=cancelunderclock/alarm_set_valuemapped back to alarm clarification instead of closing the clock value prompt. Current source now treats clock value empty turns as local no-input and maps value-prompt cancel to local clockcancel. - Photo/gallery cleanup improved: the blue-ring/listening state appeared to settle, create keeper yes/no could complete, and robot logs showed photo adoption/upload plus
it's a keeper. - Photo/gallery still has spotty speech recognition. Empty ASR under
gallery/gallery_previewcaused the other observedI heard you.after gallery opened. Current source now treats gallery preview empty turns as local no-input instead of relaunching Nimbus fallback speech. - No
ffmpeg/whisper.cpperror was evident in thejibo test 24websocket timeline. Remaining alarm/gallery failures are now mostly local no-input handling and STT/recognition quality, not decode failures.
Release Rhythm
This is the working pattern for each hosted-cloud release:
- Pick a narrow source-backed feature or compatibility slice.
- Confirm the stock payload shape from captures, Pegasus, the JiboOS reference tree, or live logs.
- Implement the smallest
.NETpath that can be tested honestly. - Add focused tests around routing, websocket payload shape, and state behavior.
- Run the stock robot live test, collect captures, and record the result before moving on.
- Keep regressions and bug fixes in the current release; roll larger follow-up work into the next version.
For 1.0.18, the remaining release work should stay small: finish one or two feature slices, run the live regression pass, and only patch bugs found in that pass before calling the version complete. 1.0.19 should then reopen the broader feature queue.
Current Code Truth
The hosted .NET cloud is a modular monolith:
Jibo.Cloud.Api -> Jibo.Cloud.Application -> Jibo.Cloud.Domain -> Jibo.Cloud.Infrastructure
Current API and protocol scope:
- HTTP
X-Amz-Targetdispatch throughJiboCloudProtocolService /healthdiagnostics- WebSocket acceptance for
api-socket.jibo.com,neo-hub.jibo.comlisten, andneo-hub.jibo.com/v1/proactive - token/session issuance for account, hub, and robot startup flows
- starter account, notification, loop, media, key, person, backup, robot, update, and upload/log handling
- media lookup through
/media/{path} - no placeholder no-op update from
GetUpdateFromwhen no staged update exists
Current websocket scope:
- long-lived cloud session state separated from per-turn websocket state
LISTEN,CONTEXT,CLIENT_NLU,CLIENT_ASR, and binary-audio handling- pending listen setup packets kept pending instead of finalized as turns
- buffered Ogg/Opus audio preservation per turn
- synthetic transcript hint support for fixture-driven parity
- opt-in local
ffmpegpluswhisper.cppSTT path for discovery - local whisper only attempts external decoding when buffered audio contains an Opus identification header
- auto-finalize thresholds for buffered audio after a real listen phase
- late-audio ignore windows after completed turns
- no-input local completion for constrained prompts, clock value prompts, and gallery preview prompts
- unknown inbound websocket types dropped silently instead of echoing stock-OS-unknown OpenJibo events
- file telemetry and fixture export for HTTP, websocket, and turn captures
Current state and persistence scope:
InMemoryCloudStateStoreremains the runtime store- a local JSON persistence bridge is enabled by default at
App_Data/cloud-state.json - persisted state currently covers staged updates, media metadata, and backup metadata
- this is a bridge toward Azure SQL and Blob Storage, not the final hosted storage architecture
Implemented In Current 1.0.18 Source
The following behavior is present in source and covered by focused tests:
cloud versionspeech and/healthversion reporting shareOpenJiboCloudBuildInfo.Version- apostrophes are no longer escaped to
'in spoken ESML, while&,<,>, and"remain escaped - radio voice launch supports
open the radioand genre launch such asplay country music, using local@be/radiomenupayloads,SKILL_REDIRECT, and silent completion - news has a first Nimbus-shaped cloud path using
match.cloudSkill = newsand anewsSKILL_ACTIONwith synthetic briefing content - stock-shaped clock handoffs cover time, date, day, clock open, timer/alarm menu, timer/alarm value, timer/alarm clarification, and timer/alarm delete
- alarm parsing covers forms such as
7:30 am,830,8 30,7, 44,10-25,10:25 pm, and10 25 p m - ambiguous alarm times can prefer the next local occurrence when the robot context includes
runtime.location.iso - short clock value follow-up transcripts are accepted under
clock/alarm_set_valueandclock/timer_set_valueinstead of being dropped before parsing CLIENT_NLU intent=setwith onlydomain=alarmstays on the local clock clarification path instead of defaulting to a fabricated timeCLIENT_NLU intent=cancelonclock/alarm_timer_query_menucan reuse the last active clock domainCLIENT_NLU intent=cancelonclock/alarm_set_value/clock/timer_set_valuemaps to local clockcancelinstead of re-asking for a value- photo flows route
open photo galleryto@be/gallery,snap a pictureto@be/create/createOnePhoto, andopen photoboothto@be/create/createSomePhotos - passive gallery/create context does not reopen a stale cloud turn
- media metadata persists across store recreation and
/media/{path}can serve the current text-body placeholder payload - constrained yes/no handling covers
clock/alarm_timer_change,clock/alarm_timer_none_set,create/is_it_a_keeper,shared/yes_no,settings/download_now_later,surprises-date/offer_date_fact,surprises-ota/want_to_download_now, and$YESNOhints - outbound constrained yes/no responses strip unrelated
globals/*rules so stock OS stays local - no-input fallback for constrained yes/no prompts emits local
LISTEN/EOSinstead of relaunching generic Nimbus speech, includingshared/yes_noafter STT failure - no-input fallback for clock value prompts and
gallery/gallery_previewemits localLISTEN/EOSinstead of genericI heard youNimbus speech - repeated empty
create/is_it_a_keeperreplies redirect to@be/idleafter the second miss so the photo/create flow can settle instead of leaving a stale listening state - local whisper skips buffered audio turns that do not contain
OpusHead, preventing a knownffmpegfailure path from becoming the noisy failure mode - Word of the Day launch, spoken guesses, structured
CLIENT_NLUguesses, hint-order guesses, fuzzy hint matching, right-word cleanup, and late audio cleanup are covered in the websocket layer
Reference Sources
Use these sources as evidence, not as code to copy blindly:
- OpenJibo Node oracle: open-jibo-link.js
- Current hosted
.NETcloud: src/Jibo.Cloud/dotnet - Live captures and robot logs:
.\artifact-output - User-provided original source snapshot:
..\jibowhen extracted locally - Original Pegasus cloud source inside that snapshot:
pegasus - Original SDK and skill source inside that snapshot:
sdk - JiboOS reference tree:
..\JiboOS - JiboOS skill snapshot:
..\JiboOS\opt\jibo\Jibo\Skills\@be
The Pegasus tree is especially useful for cloud service intent: packages/hub documents /v1/listen, /nlu, and /asr; packages/lasso documents credential and provider aggregation; packages/history and the architecture materials are useful for future memory and proactivity work.
The JiboOS trees are especially useful for local skill ownership and payload shape: @be/clock, @be/gallery, @be/create, @be/radio, @be/nimbus, @be/settings, @be/surprises*, @be/restore, @be/who-am-i, and @be/idle.
The original test suites are useful as behavior contracts before more live-device trial and error:
..\jibo\sdk\skills\clock\tests\AlarmTimerdocuments alarm/timer state expectations. Cancel at the alarm value prompt exits without scheduling; no-alarm queryyesredirects to the value prompt whilenoexits without touching KB/scheduler; existing-alarmkeeppreserves KB/scheduler whiledelete,change, andcancelclear it; cross-domain cancel uses theOtherSetyes/no branch before deleting the other clock domain...\jibo\sdk\skills\gallery\testsdocuments gallery ownership. Empty galleryyesredirects to@be/create, empty gallerynoexits, media-load failure exits, gallery/item views lifecycle out around two minutes, and delete confirmation only deletes on a positiveyes...\jibo\sdk\skills\surprises-ota\tests\OTASurprise.test.jsshows OTA/backup surprise priority is robot-local and rate-limited by status plus last-notification timestamps. Backup-in-progress sluggishness should be investigated as local scheduler/status behavior before assuming a cloud backup API issue...\jibo\sdk\skills\nimbus\testsand..\jibo\pegasus\packages\integration-tests-int\src\listen*.test.tsshow the cloud/Nimbus contract: listen transactions emitSOS,EOS, andLISTEN, with optionalSKILL_ACTION; matched responses preservematch.skillIDormatch.cloudSkill;CLIENT_ASRandCLIENT_NLUshould both be first-class test inputs...\jibo\pegasus\packages\report-skill\tests\subskills\News.test.jsis the best source-backed guide for news expansion: use category preferences, filter unusable or duplicate items, gate adult headlines for children or unidentified speakers, and provide image metadata alongside spoken headlines.
When sources disagree, prefer the newest live stock-OS capture for runtime behavior, then stock robot source for local ownership, then Pegasus for original cloud intent, then Node for known working compatibility behavior.
1.0.18 Closeout Gates
Before calling 1.0.18 complete, prove or explicitly defer these:
- Run the focused
.NETcloud test suite after the last feature slice. - Confirm the running robot build reports cloud version
1.0.18. - Regression test alarm flows again after the
jibo test 24fixes: set with explicit time, set with compact/spoken/comma-separated time, clarify missing time, replace an existing alarm, cancel/delete by voice, cancel out of a value prompt, and verify the menu agrees. - Regression test photo/gallery flows again after the
jibo test 24fixes: open gallery, answer the stockshared/yes_noprompt with a transcript-bearingyes, hand into create, take one photo, keep it, and avoid blue-ring orI heard youstale turns. - Live-test radio launch:
open the radiopassed injibo test 22; re-runplay country musicif that exact phrase was not captured. - Treat basic news as live-proven by
jibo test 23; defer provider-backed or category-expanded news unless it is chosen as an optional feature slice. - Recheck constrained yes/no prompts for update/backup/share/gallery/alarm replacement without leaking global rules.
- Recheck that stock OS no longer logs OpenJibo-only websocket events such as synthetic pending/context/ack packets from the current build.
- Recheck backup/update behavior with explicit attention to robot-local
jibo.scheduler.backupStatus, CPU/load, and whether the deployed cloud is involved at all. - Treat remaining empty-ASR,
ffmpeg, orwhisper.cpptranscript failures as STT work unless the capture proves a separate turn-routing regression.
Known Gaps
These are not blockers for calling 1.0.18 complete unless the live test shows a regression in a current release path:
- local
whisper.cppSTT remains a discovery seam, not production ASR - media upload/body handling is not binary-safe enough for final gallery originals and thumbnails
- state persistence is local JSON, not Azure SQL / Blob Storage
- update, backup, and restore are not end-to-end proven, and the
jibo test 22sluggishness appears tied to robot-local backup status/load - deployed-build verification needs to prove that synthetic OpenJibo websocket events are gone from the hosted artifact, not just from source
- news content is synthetic;
jibo test 23proved the path but not live provider-backed headlines - gallery
shared/yes_nostill needs a successful transcript-bearing liveyespass - weather, calendar, commute, personal report, identity, memory, and proactivity are still mostly discovery or placeholder content paths
- volume, stop, robot age, and command-versus-question personality routing are not implemented yet
1.0.19 Direction
After 1.0.18 is tested and tagged, 1.0.19 should move back into feature work:
- one lightweight device-control feature, most likely stop or volume
- end-to-end update/backup/restore proof
- STT reliability improvements, including noise screening and a managed STT comparison
- provider-backed first content path, likely news or weather
- hosted capture/export boundary for group testing
- continued Pegasus/JiboOS-backed mapping for proactivity, memory/history, Lasso-style aggregation, and identity
Azure Direction
The target hosted footprint remains:
- Azure App Service for HTTP and WebSocket traffic
- Azure SQL for accounts, devices, sessions, host mappings, updates, media metadata, and provisioning records
- Azure Blob Storage for media bodies, upload artifacts, update payloads, and curated capture bundles
- Azure Key Vault for secrets and certificates
- Application Insights for diagnostics and live-test observability
Local JSON persistence is only a stepping stone. Do not design new feature slices as if local file state were the final hosted store.