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.

What changes when you filter this same sample?
View / actionSample resultInterpretation
These unfinished items, with no other filters2 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 example2 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.

Source-read time is not the phone's last download
SignalSource / README meaningWhat it does not establish
date_strThe 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_failedDistinguish 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 warningsThe 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 adapterThe 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 write

Swipe to read all columns. Keyboard users can focus the table and use the arrow keys.

Read-only → explicit phone confirmation → receipt or uncertain-stop
StageRequired conditionStop / readback boundary
Read-only / draftFilters 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 confirmationFetch 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 / receiptPersist 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 / stopAfter 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

What this demonstration has not accepted

Source evidence and next steps

Setup checks · Data and permission boundaries · Voice-draft choices and handoff · Back to capabilities