Mobile Agent decisions: read first, then confirm
Yihu PM Radar reads your own JSON export or compatible HTTPS ledger feed and filters items per workbench. Seeing a task does not authorize a reply or prove execution. Two synthetic records illustrate filters, source freshness, phone confirmation and receipts. Watch is a paired-iPhone companion, not an independent approval endpoint.
Minimal synthetic JSON, not a live service
This example has two synthetic items in project demo. example.invalid is not a service endpoint; reply_supported=false marks the sample as not supporting replies and does not replace server authorization. date_str is a fixed demonstration time, not refreshed with the website clock. A later import may appear stale; do not relabel it as live data. Never publish private ledger data or credential-bearing feeds.
Scroll sideways to read the full content. Keyboard users can focus this block and use the arrow keys.
{
"date_str": "2026-10-18 09:00",
"decisions": [
{
"id": "demo-decision",
"project": "demo",
"status": "等你决策",
"title": "Choose a synthetic option",
"next": "Read the sample evidence; do not execute.",
"url": "https://example.invalid/tasks/demo-decision"
},
{
"id": "demo-acceptance",
"project": "demo",
"status": "等你验收",
"title": "Review a synthetic preview",
"next": "Inspect the synthetic preview; do not send a reply.",
"url": "https://example.invalid/tasks/demo-acceptance"
}
],
"active": [],
"stale": [],
"cold": [],
"tasks": [
{
"id": "demo-decision",
"project": "demo",
"status": "等你决策",
"title": "Choose a synthetic option",
"next": "Read the sample evidence; do not execute.",
"url": "https://example.invalid/tasks/demo-decision"
},
{
"id": "demo-acceptance",
"project": "demo",
"status": "等你验收",
"title": "Review a synthetic preview",
"next": "Inspect the synthetic preview; do not send a reply.",
"url": "https://example.invalid/tasks/demo-acceptance"
}
],
"reply_supported": false,
"source_refreshing": false,
"source_refresh_failed": false
}date_str, decisions, active, stale and cold are snapshot fields. tasks repeats the two records so this example has an explicit full-task collection rather than a legacy incomplete-ledger notice. Raw status values remain 等你决策 / 等你验收; translating display prose must not invent source statuses. There are no tokens, accounts, real items or writable services here.
What changes when you filter this same sample?
Swipe to read all columns. Keyboard users can focus the table and use the arrow keys.
| View / action | Sample result | Interpretation |
|---|---|---|
| These unfinished items, with no other filters | 2 items: demo-decision and demo-acceptance. | A count in this synthetic snapshot, not your real project count or two completed tasks. |
| Exact status filter: 等你决策 | 1 item: demo-decision. | Changes the visible subset, not source status, and does not start execution. |
| Exact status filter: 等你验收 | 1 item: demo-acceptance. | Awaiting acceptance is not accepted; inspect evidence and the next step on the phone. |
| Clear filters back to the unfinished scope in this example | 2 items. | The source is unchanged. Project, priority, search and status conditions intersect; a zero under other restrictions is not proof of no tasks. |
tasks is the full-task collection and decisions is the pending decision/acceptance subset. Current Swift management counts and status groups use filtered full tasks; decisions must not be treated as the whole ledger. Completed/on-hold items are hidden by default and available through history. Cache age and Git activity do not determine completed or blocked status. [R1][R7]
Source-read time is not the phone's last download
Swipe to read all columns. Keyboard users can focus the table and use the arrow keys.
| Signal | Source / README meaning | What it does not establish |
|---|---|---|
| date_str | The last successful source read. The current model parses yyyy-MM-dd HH:mm in UTC+08:00; this fixture intentionally fixes it. | A refresh tap, phone download or cache hit cannot make an old source-read time fresh. |
| source_refreshing / source_refresh_failed | Distinguish revalidation from failed source reads. The phone can paint bounded cache and make one no-cache follow-up joining the same read, without a polling loop. | Keeping the old snapshot after failure is not successful refresh. Missing new items must not be counted as zero. |
| Stale / future-clock warnings | The current model marks data older than 24 hours stale and warns when the source time is more than five minutes ahead. These are source-freshness signals. | Old cache does not make a task paused or blocked; task state comes from explicit source fields. |
| Optional read-only adapter | The README describes request-triggered bounded memory caching: 30 seconds fresh, at most five minutes old while revalidating. Private access/permission checks remain separate. [R6] | These are this adapter's policies, not a guarantee for every JSON service or of new business data every five minutes. |
Radar feeds do not reuse web cookies, store feed credentials or follow redirects; the README currently directs authenticated feeds to file export. This differs from configuring a browser workbench origin. Do not fix access by exposing public ports, removing authentication or putting passwords in URLs; use the existing authorized private path. [R2][R5]
Read-only → explicit phone confirmation → receipt or uncertain-stop
This is the optional write path described by source/README, not permission enabled by this fixture: reply_supported=false and no reachable service are provided. Actual replies require separate server authorization and eligible original items.
Scroll sideways to read the full content. Keyboard users can focus this block and use the arrow keys.
Read snapshot / filter (no status write)
↓
Eligible original target + separate server write authorization?
├─ No → read-only / retain draft → stop
└─ Yes → fetch fresh target/version → full phone review + explicit confirmation
↓
persist the same request_id → server submission
├─ recorded receipt → recorded, awaiting owner handling (not execution/acceptance)
└─ timeout / uncertainty → freeze input, read back the same request; no blind resend
Changed target/source → fresh read and confirmation; unresolved is not proof of no writeSwipe to read all columns. Keyboard users can focus the table and use the arrow keys.
| Stage | Required condition | Stop / readback boundary |
|---|---|---|
| Read-only / draft | Filters only read. Stay read-only without separate server write permission or an eligible target. | Visibility, Watch visibility or history-read access do not grant write authority. |
| Explicit phone confirmation | Fetch current title, link, status, next step and the complete reply, then let the user confirm in the second confirmation view. | Changed source/target versions require new confirmation; an old cached target is not a current write credential. |
| Submit / receipt | Persist request identity before submission; the server checks target/authority. Only a recorded receipt establishes the reply was recorded. | Recording a reply does not change task status, execute an Agent, merge or deploy; later handling needs separate evidence. |
| Uncertain / stop | After timeout or an unclear result, retain pending state and read back the same request. A lost receipt is not proof of no write. | Do not generate a new request to resend blindly or treat an absent result after server restart as proof no submission occurred. |
This guide supplies no write-enabling command or real reply endpoint and does not operate a service. Request/receipt guards are not an end-to-end exactly-once guarantee; actual device/service replies still need their original acceptance. [R3][R5][R6]
Watch and notifications: prerequisites before promises
- The watchOS 11+ companion receives pending decision/acceptance summaries through the paired iPhone's WatchConnectivity. The phone bridge checks pairing and Watch-app installation. This is not arbitrary Agent-backend connectivity or transfer of complete source data/credentials. [R4]
- Selected items or protected drafts can hand off to the phone. A draft-saved acknowledgement only means the phone retained the proposal, not that a server reply was recorded. Fresh phone target checks and explicit confirmation remain necessary; direct Watch writes/standalone approval are not authorized. [R4]
- A JSON GET feed is not a push event source. Native notifications and mirroring depend on compatible service, permission and device support. Notification-event parsing code does not prove an authorized upstream event source or delivered push. No new notification backend, polling or independent Watch APNs is enabled here. [R1][R4][R5]
What this demonstration has not accepted
- Only synthetic JSON, offline model decoding/filtering and static page checks are involved. No real device import, private ledger, service login, reply, Watch pairing or notification registration was tested.
- Read/filter results, a phone-saved draft, a server-recorded reply and a handled/executed task are different states. Displayed content cannot substitute for device reply or push-delivery acceptance.
- No backend, signing, account credentials or preconfigured writable feed is supplied. There is no promise of full offline behavior, end-to-end exactly-once or autonomous operations; use your trusted services and original authorization gates.
Source evidence and next steps
- [R1] Snapshot fields, exact filters, source-time parsing
- [R2] Bounded feed reads, one revalidation follow-up, cache storage
- [R3] Phone confirmation, pending request and receipt/readback
- [R4] Paired-phone Watch summaries and protected draft acknowledgement
- [R5] README: workbenches, Watch, notifications and reply prerequisites
- [R6] Optional private read adapter and separately authorized reply path
- [R7] Current management counts, status groups and clear-filter behavior
Setup checks · Data and permission boundaries · Voice-draft choices and handoff · Back to capabilities
