Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
a0b2919
feat(mobile): add trusted TOB UAT import and WorkOS sessions
DoodleBears Oct 17, 2026
7cd170b
feat(mobile): allow trusted cloud configuration text import (#2101)
DoodleBears Oct 17, 2026
2169633
docs: avoid cloud session ADR number collision (#2101)
DoodleBears Oct 17, 2026
1a699f4
docs: capture native TOB configuration import evidence (#2101)
DoodleBears Oct 17, 2026
e48712c
test: prepare real UAT sessions for native cloud verification
DoodleBears Oct 17, 2026
913aea0
test: bound native driver diagnostics and require a result
DoodleBears Oct 17, 2026
c12bc79
test: handle Hermes async fixtures and isolate simulator targets
DoodleBears Oct 17, 2026
17f6c0b
docs: record unattended native UAT session acceptance
DoodleBears Oct 17, 2026
bf91546
test: declare native UAT driver contracts for source checks
DoodleBears Oct 17, 2026
b341c64
test(mobile): drive native AuthKit callback with local emulator
DoodleBears Oct 17, 2026
b61c4e1
docs(mobile): publish bounded native browser callback evidence
DoodleBears Oct 17, 2026
027cb08
style: format browser acceptance report and counters
DoodleBears Oct 17, 2026
459c07d
docs(mobile): record real Hosted AuthKit UAT acceptance
DoodleBears Oct 17, 2026
56d53e2
feat(mobile): create and select cloud organizations
DoodleBears Oct 17, 2026
a616023
Merge current main into T1 organization slice
DoodleBears Oct 17, 2026
d9fa889
fix(mobile): bind workspace draft to selected version
DoodleBears Oct 17, 2026
f89d055
test(mobile): satisfy strict organization result indexing
DoodleBears Oct 17, 2026
d4ce602
docs: document cloud organization acceptance and resolve ADR number
DoodleBears Oct 17, 2026
494a20f
fix(mobile): retain pending organization creation on identical import
DoodleBears Oct 17, 2026
1b39324
fix(mobile): discard stale organization draft on reselection
DoodleBears Oct 17, 2026
9de7c56
docs: publish UAT mobile organization acceptance
DoodleBears Oct 17, 2026
9d337d1
feat(mobile): prepare default workspaces for ordinary cloud users
DoodleBears Oct 17, 2026
4fa835f
Merge remote-tracking branch 'origin/main' into codex/cloud-user-onbo…
DoodleBears Oct 17, 2026
00d9bcc
test(mobile): assert ordinary user role in native checkpoints
DoodleBears Oct 17, 2026
9f71dd3
docs: fix onboarding release fragment metadata
DoodleBears Oct 17, 2026
f520d81
fix(test): declare ordinary role in native fixture contract
DoodleBears Oct 17, 2026
0798329
fix(test): report actual verified instance role in UAT evidence
DoodleBears Oct 17, 2026
d94a95c
docs: publish ordinary-user multi-workspace simulator evidence
DoodleBears Oct 17, 2026
3b3ae6a
feat(mobile): create cloud channels and exchange durable text
DoodleBears Oct 17, 2026
7ceab0d
style: format channel release fragment
DoodleBears Oct 17, 2026
eccc5cf
fix(mobile): reveal cloud message input above keyboard
DoodleBears Oct 17, 2026
58d277f
fix(mobile): reserve wrapped cloud actions above keyboard
DoodleBears Oct 17, 2026
47ed7d3
style(mobile): format channel keyboard offset
DoodleBears Oct 17, 2026
f4dd6dc
fix(mobile): include keyboard prediction margin for cloud action
DoodleBears Oct 17, 2026
6704326
fix(mobile): theme cloud channel inputs in dark mode
DoodleBears Oct 17, 2026
5d2ef0f
fix(mobile): keep cloud send action compact at large text sizes
DoodleBears Oct 17, 2026
29785b3
test(mobile): publish channel UAT evidence (refs #2137)
DoodleBears Oct 17, 2026
6048b8a
feat(mobile): invite and accept cloud workspace members
DoodleBears Oct 17, 2026
4b424b5
Merge remote-tracking branch 'origin/main' into codex/2145-cloud-invi…
DoodleBears Oct 17, 2026
acfbc58
docs: resolve cloud-session ADR number collision (#2145)
DoodleBears Oct 17, 2026
0ce65b2
test(mobile): record native UAT organization invitations (#2145)
DoodleBears Oct 18, 2026
93a332a
docs: correct baseline screenshot provenance (#2145)
DoodleBears Oct 18, 2026
c146d54
feat(mobile): invite and open isolated cloud channel guests
DoodleBears Oct 18, 2026
cdc888b
fix(mobile): name the channel invitation destination clearly
DoodleBears Oct 18, 2026
77cd444
fix(mobile): pass selected channel name into invitation form
DoodleBears Oct 18, 2026
6f4d99f
fix(mobile): distinguish accepted guest access from workspace membership
DoodleBears Oct 18, 2026
250c88c
fix(mobile): use single-action keyboard spacing for guest composer
DoodleBears Oct 18, 2026
bc08a47
fix(mobile): retain prediction-bar clearance with compact guest action
DoodleBears Oct 18, 2026
55b546c
test(mobile): record UAT channel guest lifecycle evidence
DoodleBears Oct 18, 2026
f25f598
feat(mobile): provision channel Agents with private credential handoff
DoodleBears Oct 18, 2026
dc3ee2f
fix(mobile): follow source comment policy for Agent handoff (#2151)
DoodleBears Oct 18, 2026
ffaaef6
test(mobile): record channel Agent UAT lifecycle evidence (#2151)
DoodleBears Oct 18, 2026
8586130
feat(mobile): request bounded Agent health checks (#2153)
DoodleBears Oct 18, 2026
c15f5b0
docs: format channel Agent verification evidence (#2151)
DoodleBears Oct 18, 2026
81b98ea
Merge branch 'codex/2151-channel-agents' into codex/2153-agent-health…
DoodleBears Oct 18, 2026
e63bcdc
test: record native UAT Agent health check evidence (#2153)
DoodleBears Oct 18, 2026
7c4d00e
docs: record mobile work-request authority and retry boundary (#2153)
DoodleBears Oct 18, 2026
1a4983f
Connect channel-scoped cloud Agents through native Host Messaging
DoodleBears Oct 18, 2026
eee4047
fix: preserve recovery mode with cloud messaging provider
DoodleBears Oct 18, 2026
7c7f1e7
docs: record two Host UAT transport checkpoint
DoodleBears Oct 18, 2026
416ac3b
fix: enforce cloud work policy across messaging wake paths
DoodleBears Oct 18, 2026
bdf6d5e
docs: record cloud permission and crash recovery UAT
DoodleBears Oct 18, 2026
94b1749
docs: publish cloud permission and recovery evidence
DoodleBears Oct 18, 2026
f02c242
feat: run bounded cloud work through native Bot tool and CLI
DoodleBears Oct 18, 2026
247a727
test: qualify native cloud work and dedicated CLI parity
DoodleBears Oct 18, 2026
d90f28b
docs: qualify phone to native cloud Hosts in UAT (refs #2155)
DoodleBears Oct 18, 2026
c183a2d
docs: record live cloud work replay permission fences (refs #2155)
DoodleBears Oct 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .agents/skills/verify-deepseekbot/features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ The check fails for a missing feature row, required section, local link or scrip
an index row's scripted journeys disagree with its feature file. It runs in lint. Passing
checks only reference integrity: update and run the affected paths when the product changes.

| Cloud Agent Host connections | yes for Agent response; no for credential management | isolated Host plus real TOB UAT, two Hosts for collaboration | [cloud-host-connections.md](cloud-host-connections.md) |
| IM conversation mirroring and forwarding settings | no for settings; yes for a model-generated reply | `verify-app` settings path; real IM destination required for delivery | [im-conversation-mirroring.md](im-conversation-mirroring.md) |

## Not mapped yet
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Cloud Agent Host connections

## Sub-features

Explicit cloud credential import, existing Bot binding, typed source delivery, replay, connection removal and bounded health work.

## How to get to it (user POV)

Import a trusted private Agent credential with `deepseekbot cloud import --input-stdin`, then open Bot settings → Apps and bind the returned account to one local Bot. CLI parity: `cloud list`, `cloud policy --input-stdin`, `cloud remove --input-stdin --confirm`, `im-bind <bot> --app <cloud-id>` and `im-status <bot>`.

## Driving it with verify-app

Reserve the shared QA lane before starting Hosts. Use two distinct isolated DSH Profiles, ports, local Bots and cloud Agent credentials in a synthetic UAT channel. Never reuse another task's running Host or move its credentials.

1. Before import, capture the Bot's existing Apps list. Import through stdin and reopen the list; verify canonical remote name/account and explicit binding. Capture light/dark evidence; do not capture the private input or Host login URL.
2. Send one typed request to the bound remote Agent. Correlate Cloud channel sequence, local Source Event, Inbox admission and Orchestrator run. Ordinary unrelated text and result messages must not independently wake the Bot. Repeat with explicit ordinary-message immediate wake and a local Channel bridge whose members wake on all messages; unauthorized requests stay context-only. Revoke the local allow-list after admission and check current source consumption refuses execution.
3. Interrupt delivery acknowledgement, resume, and verify one canonical source and one admission. Plain HTTP source tests are not a real network-interruption result.
4. Remove the connection with its current revision. Confirm traffic stops before credential cleanup and that responses already in flight cannot advance the checkpoint. Retry failed cleanup; reimport must require explicit local policy again.
5. Use `cloud-work <bot> --input-stdin` with an admitted Source Event ID to inspect/execute/forward through the same Tool implementation. Verify pause/revocation, malformed canonical responses, expired requests and recovery from uncertain result/forward delivery. No arbitrary shell or supplied Human identity is accepted.
6. For the full collaboration gate, separately prove the bounded work owner, original-Human policy, A-to-B forwarding, one execution, result delivery and both Host restarts through real Cloudflare UAT. Independent Node processes, fake model adapters and source tests do not pass this gate.

## Gotchas

On the Chinese shell, pass `--locale zh --bot-mode`. Open the Messages rail panel before selecting a local group. Wait for that group's composer, not just its text: a sidebar preview can satisfy a text wait while the main pane remains Home. Inspect the screenshot and ARIA tree before accepting the journey.

HTTP history is the first transport; WebSocket remains separate. Import/binding does not grant shell access, remote approval authority, or membership in another organization. The protected local steward Tob is not this cloud Agent. Native/phone/Android and Human QA remain separate evidence categories.
67 changes: 67 additions & 0 deletions .github/pr-screenshots/2157-cloud-host/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Host cloud connection UAT checkpoint

Issue #2155 / Draft #2157; two distinct isolated DSH Profiles and Bots, real Cloudflare UAT. No Prod or merge.

- Initial import/binding runtime: `1a4983f5a69e7f5c7d44ef9fae421912852fde7e`.
- Restart/readback and after screenshots: `eee4047bf8ca51dcf81a2fadfc1935e15f0dc629`.
- Cloud runtime: `3eeed5b05782276b1a02cc2412dd04ab0ec60bca`, schemas 5/4/5.
- `context-replay-light.png` / `context-replay-dark.png`: actual local Messages panel after permission and crash tests, 1440×900, Chinese locale, zero browser-console issues. The three visible messages correlate with canonical local group history; the right pane has no task Session. This image alone does not prove absence of execution.
- Permission/removal/interrupted-checkpoint runtime: `416ac3bec6f5ce095220feb84f09538ea7e748db`.
- Before image shows the imported account **before binding**, not a baseline without this feature. After images show the existing Apps surface retaining its binding after restart. Viewport 1440×900, Chinese locale. Browser console checks reported zero issues. Images were visually inspected.

## Observed

Private CLI import qualified separate channel Agents and saved credentials through the native Credentials provider. A bound through the actual Apps picker; B bound through the parity CLI. Both reported receiving. Human plain text advanced both cursors without a new model turn. Explicit Messaging grants then permitted one fixed CLI send from each real Host; cloud history confirmed the two distinct canonical Agent authors. Both Profiles restarted without deletion; retrying the original Outbox request IDs retained the same receipts and exactly four total cloud messages. The fourth message was a fixed health request while both local work allow-lists were empty; A's model trace stayed at its earlier successful local DM turn, and B still had no model session. This is not an execution-ledger proof.

The initial OpenCode Go model probe failed with quota 429. Only the two synthetic Bots were changed to the already configured official DeepSeek route; A's real DM returned 43. This does not prove cloud work execution or B model readiness.

## Permission and recovery follow-up

`permission-recovery-uat.json` records the next real UAT gate on runtime `416ac3bec`:

- An explicit Messaging grant allowed collection of ordinary text. Even after setting its ordinary wake to immediate and bridging it into a local group whose Bot wakes on all messages, plain text and a typed request from a Human absent from the cloud allow-list remained context. Both appeared in canonical local group messages; the prior model turn did not change. Temporary policy overrides were restored.
- Removing Host B's connection stopped delivery and confirmed native credential deletion. A subsequent cloud message left B's cursor unchanged while disabled. Reimporting the original private credential reset local work policy to default-deny and resumed history. This tests local removal; it does not claim remote Agent revocation.
- An external Node preload, scoped to Host A's exact temporary Profile and cursor statement, sent SIGKILL after Source Event/Inbox commit but immediately before cursor update. The stopped Host had one canonical source, one admission and cursor 8. A clean restart without the preload replayed the cloud message, retained those same counts and advanced to cursor 9. The model turn stayed unchanged. This is deliberate fault injection against a real UAT message, not an unmodified-process crash claim.
- Both task-owned Hosts are healthy after restoration. No other Profile, native device or production resource was changed.

Before the permission fix, a focused regression using the real Core/Messaging implementation reproduced an unauthorized ordinary-message wake. After the fix, the cloud suite passed 14 tests and the wider Messaging boundary set passed 175. Current source CI passed: [run 39093482065](https://github.com/BotHarness/DeepSeekBot/actions/runs/39093482065). The live-model workflow was skipped; the local DM and UAT observations above are separate evidence.

## Retained failures and limits

Initial English navigation selector did not match the Chinese shell. The binding action succeeded, but waiting for nonexistent “已绑定” text timed out; formal readback and fresh screenshots confirmed the actual Bot-name/unbind state. Sandboxed process checks falsely reported dead Hosts; checks with local process access passed, and the attempted relaunch safely refused a running PID. No Profile was replaced.

Initial CI had two endpoint inventory failures and one real recovery-mode startup failure. The fix defers cloud Provider registration when the Operational Database is unavailable; 51 entry/cloud tests, direct root/mobile typechecks, build and lint passed. The aggregate typecheck wrapper hit pnpm's existing dependency-symlink task-state restriction; its two underlying checks passed separately. The follow-up source CI passed as linked above.

The interruption test's first cleanup used an unsupported `--inherit` flag for Messaging policy. The documented stdin payload restored inheritance successfully; connection traffic and Host health were checked afterward. Additional group capture attempts retained selector/locale timeouts. One text wait matched a sidebar preview while the main pane remained Home; visual inspection rejected that apparent pass. These captures are not proof of a successful message-page journey. The corrected path explicitly opens the Messages rail panel, selects the group and waits for its composer; the actual message panel and empty task-session area were visually inspected.

Pending at that checkpoint: WebSocket, organization-wide Agent membership and a fresh mobile-to-two-Host run (the latter is qualified below). The following bounded-work follow-up supersedes the earlier execution-pending status. Current-consumption policy revocation and another local Bot's lack of execution authority have source-test coverage; they are not yet a live work-execution proof. Phone, Android and Human QA are not established by this desktop Host evidence. No video was captured in this checkpoint.

## Bounded model work and restart follow-up

Runtime `f02c2423bce02c264548193ac738013f4eac83ab` / unchanged TOB UAT `3eeed5b` passed the two-Host fixed health path. After explicit owner instructions to the synthetic Bots, A called native `cloud_work inspect` and `forward`; B called `inspect` and `execute`. Channel sequences 13, 14 and 15 contain exactly the Human parent, Agent A child and Agent B result. Original Human and deadline are preserved. A ledger records zero executions; B records one. Restarting both exact Profiles and invoking the same Tool through formal CLI returned the same child and zero additional executions/messages. Local work policies were restored to deny-by-default. See [sanitized assertions](work-model-uat.json).

First attempts are retained: sending while local policy denied work and reception collected only mentions produced no accepted source; that fixture setup was corrected. A then executed the initial request locally despite its updated saved persona. A fresh explicit owner DM established the dispatcher instruction; a new request qualified forwarding. This is a model-choice result, not a silent retry of an already executed request. The initial local execution remains a separate valid result. Both Bots produced real model replies; no synthetic model adapter is used in this UAT run.

Source73tests, typecheck, lint, formatting and build passed before the runtime run. A sandboxed test invocation stalled before test output; it was terminated and the equivalent local-permission run passed in 6.34 seconds. Native phone/Android, hardware diversity, general commands, current-policy revocation during an actual effect, and video are not established by this follow-up.

The f02c2423b CI affected suite passed 2,672 tests and failed its direct-tool catalog assertion, which assumed every Bot tool uses the generic runner. The follow-up records the dedicated `cloud-work` command and makes the parity checker reject generic `bot-tool` as coverage for `cloud_work`; focused catalog/owner/checker tests passed 19. The production runtime is unchanged by that test/checker correction. A new activity capture initially used an accessibility-only label as visible text and timed out; the corrected navigation passed, but shows the owner's acknowledgement rather than the cloud result, so it is not published as work-result proof.

## Phone to both native Hosts — 2026-10-18 UAT

Mobile JS / assigned qa/batch-19: `247a727b8ee832f1fd21318b2c0063a1b2f3c53b`; installed native inputs `494a20f1e`, unchanged by this JS-only window. Host runtime remains `f02c2423bce02c264548193ac738013f4eac83ab`, cloud remains `3eeed5b`. [CI 39095884899](https://github.com/BotHarness/DeepSeekBot/actions/runs/39095884899) passed all applicable checks at 247a727b8, including the affected suite; the optional model workflow was skipped. This evidence update changes no executable code.

The actual iOS Simulator member UI selected the existing organization and host-uat channel, then pressed **Request health check** for Host UAT A. Cloud sequences **16 → 17 → 18** are the phone Human request, A's forwarded request and B's completed result. Both Hosts used real native model tools; the canonical ledgers record **A=0, B=1** executions with original Human/deadline preserved. The phone used Reload messages and visibly displayed all three records. See [machine assertions](phone-work-uat.json).

Images are English/light at 402×874, visually inspected. `phone-before.png` is the same feature before this request, not a baseline without the implementation. `phone-result.png` shows the exact three new messages. `phone-restart.png` and `phone-logout.png` show verified-session and remote-revoked states. [Request recording](phone-request.mp4) is the first 18 seconds of the post-authentication capture; [result recording](phone-result.mp4) is the full 35-second reload/scroll capture, re-encoded for size. Original local recordings remain available. No credentials or personal mailbox appear; IDs belong to synthetic test users/Agents.

Independent synthetic staging authentication was prepared through the authorized test driver; this run does not re-prove Hosted AuthKit/PKCE. Refresh through the UI rotated credentials, cold restart retained the same verified identity/session, and Sign out cleared mobile secrets while retaining trusted configuration. WorkOS readback confirmed that exact session was revoked, latest refresh rejected and baseline sessions preserved. Both independent A/B CLI sessions then passed whoami. The redundant cleanup revoke returned a generic helper failure after logout had already been verified; the exact temporary fixture was removed after those independent checks. No WorkOS configuration was changed.

Initial Metro resolved localhost to IPv6 and the Simulator could not connect to 127.0.0.1; restarting only this runner's Metro with IPv4 resolved it. A cold-start selector ran too early; the loaded page was then observed before proceeding. The generic back command is not available on the presented iOS sheet; the visible native downward-dismiss gesture returned successfully. These are retained test/setup observations, not omitted failures.

The runner closed its driver and own 8091 Metro, restored both Host work policies, and released the assigned lane. Existing shared data, three untracked QA documents, physical-phone 8097 and shared Host 39100 were preserved. No native build, install, erase, Prod operation or merge occurred. Android, physical hardware diversity, Human QA and a new text-size/theme matrix are not claimed by this increment. WebSocket, organization-wide Agent membership and wider live revocation remain open goal gates.

### Live completed-request permission fences

After the phone run, formal `deepseekbot cloud-work` exercised the same native Tool owner against those real admitted sources. Removing the original Human refused both A forwarding replay and B execution replay (`CLOUD_WORK_DENIED`). With Human authority restored but no target grant, A forwarding replay refused (`CLOUD_FORWARD_DENIED`). B could not add a second hop, A could not target itself (`FORWARD_LIMIT`), and A could not execute after committing a forward (`CLOUD_WORK_CONFLICT`). An authorized B replay returned executed0 and canonical executionCount1; cloud history remained at sequence18. All temporary policies were restored. [Assertions](work-denials-uat.json).

This closes six real completed-request denial checks; it does not simulate revocation racing a new running effect or remote Agent credential revocation. Those narrower limits remain explicit.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"runtimeSha": "416ac3bec6f5ce095220feb84f09538ea7e748db",
"cloudRuntimeSha": "3eeed5b05782276b1a02cc2412dd04ab0ec60bca",
"environment": "UAT",
"wakeBoundary": {
"runtime": "416ac3bec",
"explicitOrdinaryImmediate": true,
"localGroupWakeAll": true,
"plainAndDeniedRequestVisibleInLocalGroup": true,
"modelTurnUnchanged": true,
"cursor": 7,
"policyRestoration": "restored"
},
"localRemoval": {
"cursor": 7,
"credentialRemoved": true,
"sequence": 8,
"disabledCursorStable": true,
"restoredWithEmptyPolicy": true,
"resumedHistory": true
},
"checkpointReplay": {
"runtime": "416ac3bec6f5ce095220feb84f09538ea7e748db",
"fault": "own Host SIGKILL immediately before cursor update, external Node preload",
"interrupted": {
"sources": 1,
"admissions": 1,
"cursor": 8
},
"recovered": {
"sources": 1,
"admissions": 1,
"cursor": 9
},
"modelTurnUnchanged": true,
"policyRestoration": "restored",
"cleanupCorrection": "invalid --inherit on messaging-group-policy corrected to documented stdin inheritance"
},
"scope": "Two isolated real DSH Hosts; no bounded work executor or model forwarding yet",
"sourceCI": "https://github.com/BotHarness/DeepSeekBot/actions/runs/39093482065"
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading