docs: design Codex publishing and routine execution workflows
@@ -0,0 +1,386 @@
|
||||
# External Codex publishing into the workspace
|
||||
|
||||
Proposal, 2026-09-28. No endpoints, timers, or inference jobs in this document
|
||||
have been implemented. This supersedes the earlier proposal for app-managed
|
||||
inference and an application-owned life filesystem adapter.
|
||||
|
||||
## Responsibility
|
||||
|
||||
External Codex reads Beeper and the life filesystem, reasons about them, and
|
||||
maintains life under its existing Rensheng conventions. life remains the CRM
|
||||
source of truth. The workspace accepts structured results, persists and displays
|
||||
them, and records user decisions and requests. It does not need a new LLM loop,
|
||||
CRM compiler, or Markdown editing engine.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
T[Host timer or manual invocation] --> C[External Codex job]
|
||||
B[Beeper API / CLI] --> C
|
||||
C <-->|Read and maintain CRM| L[Rensheng / life files]
|
||||
C -->|Publish structured results| P[Application write API]
|
||||
P --> D[SQLite projections and user decisions]
|
||||
D --> U[Home / Messages / CRM]
|
||||
U -->|Requests and corrections| Q[Durable request inbox]
|
||||
Q --> C
|
||||
```
|
||||
|
||||
The existing Research chat can remain as-is. This design does not require
|
||||
removing that feature or putting its runtime in charge of CRM automation.
|
||||
Deterministic Beeper reads, live UI updates, and confirmed sends are ordinary
|
||||
application integration code; they do not imply app-owned inference.
|
||||
|
||||
## What gbrain actually does
|
||||
|
||||
Inspected revision: `e78f1c38b947b053f3a46881340f74f316be855a`.
|
||||
|
||||
- Its [cron convention](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/skills/conventions/cron-via-minions.md)
|
||||
assigns scheduling to the host. It explicitly describes a native cron
|
||||
scheduler inside `jobs work` as not yet shipped.
|
||||
- [Minions workers](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/src/core/minions/worker.ts)
|
||||
handle durable execution, leases and retries. Job idempotency and prevention
|
||||
of overlapping runs are separate concerns.
|
||||
- [Autopilot](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/src/commands/autopilot.ts)
|
||||
is a maintenance daemon, not a ready-made external Codex scheduler. The
|
||||
built-in [subagent handler](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/src/core/minions/handlers/subagent.ts)
|
||||
uses gbrain's own model/tool execution.
|
||||
- Its [page write operation](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/src/core/ops/pages.ts)
|
||||
uses request receipts, expected revisions and transactional writes. These are
|
||||
useful patterns for publishing into this app without importing its entire stack.
|
||||
|
||||
## Scheduling proposal
|
||||
|
||||
Use one external systemd timer and oneshot service, or the existing host scheduler
|
||||
if one already owns this workflow. Do not create schedules during research.
|
||||
Start with a morning brief and periodic daytime refresh; exact cadence and job
|
||||
timeout are deployment choices, not established product requirements.
|
||||
|
||||
The runner sets an explicit working directory and `CODEX_HOME`, prevents
|
||||
concurrent runs, reads the app context revision, then invokes Codex to inspect
|
||||
sources and prepare a result. It publishes through the application API and keeps
|
||||
a private result file until acknowledgment so a network retry need not repeat
|
||||
inference. Do not put credentials in prompts or command arguments.
|
||||
|
||||
Use separate identifiers for the scheduled occurrence and publish attempt. A
|
||||
retry of an unchanged result keeps its `runId`; regeneration after a conflict
|
||||
uses a new `runId`. Host logs expose started, finished and failed runs without
|
||||
dumping messages. The UI can show the last successful publication and source
|
||||
freshness; it should retain the previous good result when a new run fails.
|
||||
|
||||
Beeper events can later mark work dirty and coalesce a wake-up. Do not start one
|
||||
Codex process per message. Natural-language requests can use the same external
|
||||
worker path; a future wake-up signal should only notify that worker, not execute
|
||||
browser-supplied shell text.
|
||||
|
||||
## Write interface
|
||||
|
||||
Start with HTTP and a small CLI wrapper that accepts JSON from a file/stdin.
|
||||
Add an MCP wrapper only if useful for tool discovery; it must call the same
|
||||
validated service. HTTP, CLI and MCP are access methods, not three state stores.
|
||||
Avoid direct SQLite writes and an arbitrary SQL, shell or filesystem tool.
|
||||
|
||||
Proposed first contract, keeping the repository's camelCase JSON convention:
|
||||
|
||||
| Method and path | Caller | Purpose | Success |
|
||||
| -------------------------- | --------------------- | ----------------------------------------------------------------------- | ------------------------- |
|
||||
| `GET /api/agent-context` | Agent credential | Read revision, current projections, user decisions and pending requests | `200` |
|
||||
| `POST /api/agent-results` | Agent credential | Atomically publish a validated result and complete referenced requests | `201`; exact replay `200` |
|
||||
| `POST /api/agent-requests` | Owner browser session | Persist a natural-language request or a requested life correction | `201`; exact replay `200` |
|
||||
|
||||
Browser snapshot reads use the same application service under owner session
|
||||
authentication. An optional `GET /api/agent-results/{runId}` receipt endpoint can
|
||||
be added if exact POST replay is insufficient. No public API version prefix is
|
||||
needed for this first coordinated client/server contract.
|
||||
|
||||
The agent credential is limited to context reads and result publication. It must
|
||||
not approve a send, change login settings, or mark user decisions on the user's
|
||||
behalf. The existing session, Tailscale and Origin middleware does not accept
|
||||
this authentication flow today. Implement a narrowly scoped agent route branch
|
||||
that verifies its own credential; do not add these paths as unauthenticated
|
||||
exceptions or spoof a Tailscale identity. Use loopback locally, TLS remotely.
|
||||
|
||||
### Result shape
|
||||
|
||||
Illustrative payload, with fictional data:
|
||||
|
||||
```json
|
||||
{
|
||||
"runId": "morning-2026-09-29-attempt-1",
|
||||
"jobKey": "daily-brief",
|
||||
"expectedRevision": 42,
|
||||
"generatedAt": "2026-09-28T23:00:00Z",
|
||||
"sourceRefs": [
|
||||
{
|
||||
"id": "life-person-example",
|
||||
"kind": "life",
|
||||
"path": "people/example.md",
|
||||
"contentHash": "sha256:example",
|
||||
"observedAt": "2026-09-28T22:59:00Z"
|
||||
}
|
||||
],
|
||||
"brief": {
|
||||
"date": "2026-09-29",
|
||||
"timeZone": "Asia/Tokyo",
|
||||
"text": "Start with the meeting reply.",
|
||||
"evidenceIds": ["life-person-example"]
|
||||
},
|
||||
"people": [
|
||||
{
|
||||
"id": "person-example",
|
||||
"name": "Example Person",
|
||||
"context": "Discussing the next meeting.",
|
||||
"evidenceIds": ["life-person-example"]
|
||||
}
|
||||
],
|
||||
"activities": [],
|
||||
"replyDrafts": [],
|
||||
"retractions": [],
|
||||
"completedRequests": []
|
||||
}
|
||||
```
|
||||
|
||||
`runId` and `jobKey` are required bounded strings; `expectedRevision` is a
|
||||
nonnegative integer from the last context read. All timestamps are RFC 3339.
|
||||
The server stamps `receivedAt` and authenticated publisher identity itself.
|
||||
Dates used for the home brief include an explicit timezone.
|
||||
|
||||
People/activities/drafts are upserts with stable IDs, not position-based IDs or
|
||||
display names. People are projections of life, not independently maintained CRM
|
||||
facts. Activities use the typed contract below, with a title, references and
|
||||
evidence IDs. Drafts include canonical target/account/chat IDs, reply target,
|
||||
source message revision and candidate bodies/styles. Beeper evidence includes
|
||||
target/account/chat/message IDs and observation time; life evidence includes a
|
||||
relative path and content hash. A Git revision alone does not describe uncommitted
|
||||
life edits. Source references are data, never filesystem access instructions.
|
||||
|
||||
The app validates structure, references, bounds and permissions; it does not
|
||||
infer whether a CRM fact is true. Publisher-supplied evidence is provenance, not
|
||||
proof that the app independently verified the original file or conversation.
|
||||
|
||||
Omitted `brief` leaves the brief unchanged; empty arrays perform no upserts.
|
||||
Omission never deletes an existing item. Explicit typed retractions can withdraw
|
||||
agent suggestions but cannot delete user-owned decisions. Reject unsupported
|
||||
fields and nulls in this coordinated first version. Agree payload size, per-array
|
||||
limits and bounded context pagination when implementing; do not accept unbounded
|
||||
history or attachments through this endpoint.
|
||||
|
||||
### Atomic publication and conflicts
|
||||
|
||||
1. Scope receipts to authenticated publisher plus `runId`. Store a canonical
|
||||
payload hash. A replay with the same payload returns the original receipt;
|
||||
the same key with different content returns `409 idempotency_conflict`.
|
||||
2. Check replay before checking the expected revision. A successful retry must
|
||||
still work after unrelated later UI changes.
|
||||
3. Validate the full result, check `expectedRevision`, write projections and the
|
||||
receipt, and increment the context revision in one SQLite transaction.
|
||||
A concurrent publish or user edit yields `409 revision_conflict` and no writes.
|
||||
4. User edits, dismissals, completions and selections live separately from agent
|
||||
suggestions. A new proposal cannot revive a dismissed action or replace a
|
||||
user-edited draft. Context reads expose those decisions to Codex.
|
||||
5. Emit a browser update only after commit. On reconnect, fetch a snapshot;
|
||||
notifications are not the source of truth. A failed publication leaves the
|
||||
previous brief intact.
|
||||
|
||||
Return `{runId, revision, receivedAt}` as the receipt. Keep deduplication receipts
|
||||
for the MVP's lifetime; any future pruning must define a retry horizon first.
|
||||
Retry transient transport failures with the exact payload and key. Conflicts
|
||||
require a fresh context read and reconciliation, not blind retry.
|
||||
|
||||
Use a small stable error envelope such as
|
||||
`{code, message, details, requestId}`: `400` malformed JSON, `401` invalid agent
|
||||
credential, `403` forbidden operation, `409` conflicts, `413` oversized payload,
|
||||
`422` invalid result structure, `429` throttling, and `5xx` transient server faults.
|
||||
No partial successes. This is a new machine API; it need not refactor unrelated
|
||||
existing UI error contracts.
|
||||
|
||||
## Returning user intent to Codex
|
||||
|
||||
The app must also expose what the user did. Otherwise the next scheduled run
|
||||
cannot distinguish a stale suggestion from a deliberate dismissal or correction.
|
||||
|
||||
`POST /api/agent-requests` accepts a stable client `requestId`, a kind such as
|
||||
`refresh`, `reply-draft`, or `crm-edit`, an optional entity ID/source revision,
|
||||
and the user's text or requested edit. Persist before acknowledging. Repeated
|
||||
IDs with identical bodies return the same request; mismatches return `409`.
|
||||
|
||||
A result links each completed request using
|
||||
`completedRequests: [{requestId, sourceRefIds}]`. All source references must exist
|
||||
in the publication; a `crm-edit` completion requires a life reference with the
|
||||
resulting content hash. Reject completion of unknown or already cancelled
|
||||
requests. This validates the claimed provenance link, not the file contents
|
||||
independently.
|
||||
|
||||
A person-note edit appears as pending while external Codex applies it to life.
|
||||
It becomes confirmed only after publication references that request and supplies
|
||||
the resulting source revision. Failures keep the previous confirmed projection
|
||||
and the pending request visible. Do not label an app-only edit as already saved
|
||||
to life. Single-worker execution avoids requiring a job lease API for this MVP.
|
||||
|
||||
life changes and app publication are not one transaction. If the process stops
|
||||
between them, the next run re-reads life and checks the request's outcome before
|
||||
applying it again. Prefer desired-state edits over blind append operations and
|
||||
preserve request provenance where the life workflow permits it.
|
||||
|
||||
Actual message sending remains a separate, revision-bound user command. Publishing
|
||||
a draft or marking an agent request complete cannot send a message. Send results
|
||||
can be exposed in the next agent context for Codex to update life.
|
||||
|
||||
## First useful slice
|
||||
|
||||
Implement context read and result publish, persist them, and render a published
|
||||
brief plus a mixed activity list: weight entry, a simple optional task, routine
|
||||
steps and a reply linked to published life context. Prove duplicate replay,
|
||||
conflict handling, reload persistence and preservation
|
||||
of user decisions with fixture data. Then run one external Codex job manually
|
||||
before installing a timer. Add the request inbox when introducing on-demand
|
||||
generation or CRM editing. This order gives the agent somewhere to write before
|
||||
building automation around it.
|
||||
|
||||
The [Beeper Copilot captures](references/beeper-copilot/README.md) provide the UI
|
||||
reference for those published results: conversation list, conversation body,
|
||||
person context, evidence chips, reply candidates and explicit review.
|
||||
|
||||
## One activity list, different execution surfaces
|
||||
|
||||
Home should unify what the user needs to do, while preserving the right controls
|
||||
for each activity. A shared task abstraction does not imply a universal checkbox
|
||||
or a universal chat card. Activity ordering, deferral and visibility are shared;
|
||||
execution and completion are domain-specific.
|
||||
|
||||
| Activity kind | Inline or expanded Home UI | Completion evidence |
|
||||
| ------------- | --------------------------------------------------------------------- | ----------------------------------------------------------- |
|
||||
| `task` | Concise title, optional detail, completion control | User marks it complete |
|
||||
| `measurement` | Weight number field, unit, last recorded value/time, Save | A measurement record is saved |
|
||||
| `reply` | Person, latest relevant message, reason to reply, draft editor/review | Send is confirmed; a larger exchange may remain waiting |
|
||||
| `routine` | Ordered child activities and progress | Required children complete, or an explicit skip is recorded |
|
||||
|
||||
Use common fields such as `id`, `title`, `kind`, `evidenceIds`, `personId`,
|
||||
`parentId`, `occurrenceKey`, and optional recommendation/order metadata. User
|
||||
state (available, in progress, waiting, deferred, completed or skipped) is stored
|
||||
separately from Codex's recommendation. Each kind has a validated payload and a
|
||||
fixed application renderer; do not accept agent-generated executable UI or HTML.
|
||||
|
||||
`routine` and `optional` in the current Home sections are grouping/priority
|
||||
choices, not exclusive UI types. A weight activity can be a morning routine step;
|
||||
a reply can be optional today. A routine groups child activities rather than
|
||||
duplicating their records. Home and Messages refer to the same reply activity ID,
|
||||
so editing or finishing it in either surface is immediately consistent.
|
||||
|
||||
For example, an illustrative measurement activity published by Codex:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "weight-2026-09-29",
|
||||
"kind": "measurement",
|
||||
"title": "Log weight",
|
||||
"parentId": "morning-2026-09-29",
|
||||
"occurrenceKey": "2026-09-29@Asia/Tokyo",
|
||||
"payload": { "metric": "weight", "unit": "kg" },
|
||||
"evidenceIds": []
|
||||
}
|
||||
```
|
||||
|
||||
Codex chooses or recommends the activity; the user supplies the measured number.
|
||||
The app saves the observation and its occurrence time without invoking inference.
|
||||
Corrections preserve the observation history. Completion must reflect that save,
|
||||
not merely a checked box. The agent can read this execution evidence on its next
|
||||
run and maintain life accordingly; the app does not need to infer health advice.
|
||||
|
||||
Recurring activities need stable per-occurrence IDs: publishing tomorrow's
|
||||
routine must not reopen today's completed one. Missing time slots are valid;
|
||||
the user explicitly wants flexible daily ordering rather than a strict calendar.
|
||||
A real appointment can still retain its explicit date/time.
|
||||
|
||||
Reply completion follows the confirmed send state, not draft generation, review
|
||||
or merely pressing Send. A conversation can contain multiple distinct commitments;
|
||||
Codex determines those relationships from sources. The application stores explicit
|
||||
links and user choices without deciding that one reply resolves every commitment.
|
||||
|
||||
The resulting Home can place a weight input, a routine's next step, a reply
|
||||
preview and a simple task together. Use a compact shared outer row and expand
|
||||
the relevant controls in place; detailed conversation/CRM views remain available.
|
||||
Natural-language entry creates an external-agent request, while direct numeric
|
||||
entry, checkboxes and draft edits remain immediate deterministic UI operations.
|
||||
|
||||
## Routine execution and workstyle learning
|
||||
|
||||
The user wants to import ideal routines from life, track their execution in this
|
||||
app, and use external Codex analysis to develop a workable personal workstyle.
|
||||
This adds explicit execution analytics to the earlier reference-only routine
|
||||
concept; it does not imply that all ideals are already practiced or due daily.
|
||||
|
||||
Keep three levels distinct:
|
||||
|
||||
1. **Routine definition:** life source, stable ID, definition revision, purpose,
|
||||
trigger, steps, and completion rule. Codex publishes a structured projection.
|
||||
2. **Trial/activation:** which version is currently being tried, applicable days
|
||||
or situations, and the chosen scope. Importing an ideal into the catalog does
|
||||
not silently activate every step as a daily obligation.
|
||||
3. **Occurrence and observations:** the actual applicable occasion, its frozen
|
||||
definition revision, user actions, recorded values, skips, and corrections.
|
||||
The application is the source for execution history; life links to it rather
|
||||
than maintaining a second completion ledger.
|
||||
|
||||
An approved routine definition can be instantiated deterministically by the app
|
||||
on its recurrence or a user action such as starting/ending work. Codex need not
|
||||
run every time a routine appears. Situational occurrences should come from an
|
||||
explicit trigger or confirmed source, not an assumed event inferred by the UI.
|
||||
Keep occurrence identity stable across delayed cron runs and retries. Do not
|
||||
turn unfinished instances into an ever-growing daily backlog automatically.
|
||||
|
||||
Proposed operating loop:
|
||||
|
||||
- **Import:** Codex reads life and publishes a routine catalog with sources and
|
||||
revisions. Show what is already active and what remains an ideal/candidate.
|
||||
- **Try:** choose a small set and a review window, for example one or two weeks.
|
||||
These durations and counts are starting suggestions, not fixed app rules.
|
||||
- **Execute:** Home presents due/applicable occurrences with kind-specific UI.
|
||||
Save completion evidence as part of the natural action: entering a value,
|
||||
sending a reply, writing a resumption note, or completing a task. Optional
|
||||
friction feedback can be one tap; reporting a reason is not required.
|
||||
- **Review:** the application calculates counts from recorded events. External
|
||||
Codex reads the counts and underlying evidence, relates them to life context,
|
||||
and publishes a short review with observations, uncertainties and proposals.
|
||||
- **Adjust:** the user adopts, modifies or rejects a proposal. Codex updates the
|
||||
ideal/working procedure in life and publishes a new definition revision.
|
||||
Historical occurrences retain their previous revision and completion rule.
|
||||
|
||||
A scheduled daily job can refresh the overview, while a weekly job reviews the
|
||||
experiment. Neither creates additional inference inside the app. The publishing
|
||||
contract will need versioned routine definitions and review artifacts alongside
|
||||
activities; context reads must expose execution observations and aggregate counts.
|
||||
Those are deterministic data contracts, not a new agent runtime.
|
||||
|
||||
### Metrics that preserve meaning
|
||||
|
||||
Show counts and denominators next to percentages. For each routine revision and
|
||||
review window, report completed, partially completed, explicitly skipped,
|
||||
deferred, not applicable, and unrecorded occurrences separately. A past due item
|
||||
without an observation remains unrecorded, not verified non-execution.
|
||||
|
||||
A useful default is **recorded attainment = completed / applicable planned
|
||||
occurrences**, accompanied by observation coverage. For example, 5 completed,
|
||||
1 explicitly skipped and 1 unrecorded out of 7 applicable occasions yields 5/7
|
||||
recorded attainment and 6/7 observed outcomes. It does not prove that the person
|
||||
failed to act on the unrecorded occasion. If a resolved-outcome rate is also
|
||||
shown, label its different denominator explicitly. Keep skipped occasions in
|
||||
the planned denominator; exclude not-applicable ones with a recorded reason and
|
||||
retain plan revisions so exclusions cannot silently rewrite prior performance.
|
||||
|
||||
Do not count a routine parent and every child as independent equivalent successes
|
||||
in a global percentage. Analyze routines and steps at separate levels. Optional
|
||||
ideas that were never scheduled/adopted do not belong in the planned denominator.
|
||||
Explicitly record reduced/partial completion without silently calling it full
|
||||
completion. Measurement adherence is about saving a measurement, not moving the
|
||||
number in a preferred direction; reply counts do not measure relationship quality.
|
||||
|
||||
Attainment alone cannot establish usefulness. Add lightweight, optional feedback
|
||||
on effort and whether a routine helped, plus domain-specific evidence such as a
|
||||
resumption note being available next time. Compare versions over named periods
|
||||
and show sample sizes. Codex can suggest one change to try next, but sparse
|
||||
observations or coincident changes do not establish a causal improvement.
|
||||
|
||||
The review should answer: what was practical, where execution stopped, what was
|
||||
useful, and what small change is worth trying next. Good outcomes can include
|
||||
shortening, reducing frequency, changing the trigger, or retiring a routine.
|
||||
Do not optimize a single global completion score at the expense of the purpose
|
||||
of the work or the user's freedom to change the plan.
|
||||
@@ -0,0 +1,143 @@
|
||||
# Beeper integration research
|
||||
|
||||
Researched 2026-09-28. Proposal only; no integration was installed during research.
|
||||
|
||||
## Current direction
|
||||
|
||||
External Codex performs inference, reads Beeper, and reads/writes life under
|
||||
Rensheng conventions. life is the CRM source of truth, serving the role Scrapbox
|
||||
plays in Beeper Copilot. This application accepts structured publications and
|
||||
provides the UI, persistent execution state, and user feedback. It does not need
|
||||
a new CRM inference runtime or life filesystem editing engine.
|
||||
|
||||
Home combines routines, optional tasks, measurements and communication as
|
||||
activities, with different controls for each kind. A weight entry, reply editor,
|
||||
routine checklist and simple completion control belong in one daily overview.
|
||||
|
||||
See [external agent publishing](agent-publishing-design.md) for the concrete
|
||||
contract and gbrain cron findings, and the
|
||||
[Beeper Copilot screenshot gallery](references/beeper-copilot/README.md) for UI
|
||||
references. This supersedes earlier proposals for app-managed inference and
|
||||
direct app-to-life editing.
|
||||
|
||||
## Verified locally
|
||||
|
||||
- Beeper CLI 0.6.2 and Server run on UM790-Pro.
|
||||
- Public `GET http://127.0.0.1:23373/v1/info` returned Beeper 4.3.149 on Linux,
|
||||
running, remote access disabled and MCP enabled.
|
||||
- Discovery exposes `/v0/mcp`, `/v1/ws`, and `/v1/spec`. The live OpenAPI
|
||||
reports API version 5.0.0, distinct from the application/SDK version domains.
|
||||
- The existing CLI target `um790` successfully retrieved server info using
|
||||
`--read-only`. This is discovery verification, not proof of complete account
|
||||
synchronization or successful message delivery.
|
||||
- No private conversation bodies were fetched, and no Beeper configuration or
|
||||
messages were changed. The screenshots contain public LP demonstrations.
|
||||
|
||||
The [official CLI](https://github.com/beeper/cli) supports headless Server as
|
||||
well as Desktop. No additional GUI machine or remote tunnel is needed here.
|
||||
|
||||
## HTTP, WebSocket, MCP and CLI
|
||||
|
||||
| Interface | Role |
|
||||
| -------------------------------------------- | -------------------------------------------------------------- |
|
||||
| Beeper HTTP / CLI / SDK | Read messages, reconcile changes, perform approved sends |
|
||||
| Beeper WebSocket | Live UI changes or a coalesced signal for the external worker |
|
||||
| App write API, optionally wrapped as CLI/MCP | Receive Codex results without inference |
|
||||
| App context/request API | Expose user decisions, pending requests and revisions |
|
||||
| Browser HTTP + SSE | Persisted views, direct UI operations and update notifications |
|
||||
|
||||
Existing CLI authentication can be reused with bounded, fixed-argument
|
||||
`api get` calls and `watch --target um790 --read-only --json`. Do not expose
|
||||
arbitrary CLI/RPC command strings as agent tools. The
|
||||
[official TypeScript SDK](https://github.com/beeper/desktop-api-js) is an alternative
|
||||
after explicitly provisioning an application credential. Choose one transport
|
||||
inside the adapter; automatic CLI/SDK fallback is unnecessary.
|
||||
|
||||
The [MCP guide](https://developers.beeper.com/desktop-api/mcp/) uses Streamable
|
||||
HTTP. The [changelog](https://developers.beeper.com/desktop-api/changelog/) removes
|
||||
the old Beeper MCP SSE transport; our own browser SSE can remain.
|
||||
|
||||
## Synchronization findings
|
||||
|
||||
The running server's `/v1/spec` explicitly states that WebSocket delivery is
|
||||
at-most-once, has no replay after reconnect, and uses per-connection sequence
|
||||
numbers. The [WebSocket guide](https://developers.beeper.com/desktop-api/websocket-experimental/)
|
||||
also describes experimental status and best-effort payloads. HTTP reconciliation
|
||||
is required after disconnects and periodically. Do not start Codex per message.
|
||||
|
||||
Subscribe before initial reconciliation, track changed chats during it, then
|
||||
refetch those chats. Commit progress only after persistence. Use canonical
|
||||
target/account/chat/message IDs and revisions or content hashes. Edited/deleted
|
||||
evidence invalidates affected drafts. One missing list result does not prove
|
||||
deletion. CLI watch webhooks are best-effort and can drop on queue overflow;
|
||||
a same-machine worker avoids needing a webhook receiver, not the need to reconcile.
|
||||
|
||||
The [message API](https://developers.beeper.com/desktop-api-reference/resources/messages/methods/list/)
|
||||
returns opaque cursors. life's backfill guide records missed/duplicated pages
|
||||
when CLI message IDs were used as cursors, plus API order differing from timestamp
|
||||
order. Do not stop pagination merely because a date boundary was crossed.
|
||||
|
||||
## Reference findings
|
||||
|
||||
### life
|
||||
|
||||
`life/briefs/2026-09-25-executive-support-design.md` describes source-backed reply
|
||||
assistance, explicit review and durable personal context. Existing
|
||||
`life/docs/beeper-backfill.md` and `life/scripts/beeper_backfill.py` implement
|
||||
reviewed, resumable CLI backfill on this machine.
|
||||
|
||||
That helper is not a continuous inbox worker: discovery covers 100 recent chats,
|
||||
pages require review/acknowledgment, and some quotes, forwarded messages and
|
||||
attachments are deliberately excluded. Its output is not a complete conversation
|
||||
view. Reuse its identity/provenance rules. Its guide warns that CLI 0.6.2 raw
|
||||
`status --json` can expose credentials.
|
||||
|
||||
Codex should maintain existing life domain pages. The app displays published
|
||||
CRM projections; user corrections return as durable requests to Codex. It must
|
||||
distinguish pending corrections from confirmed life changes.
|
||||
|
||||
### gbrain
|
||||
|
||||
Inspected revision `e78f1c38b947b053f3a46881340f74f316be855a`. No Beeper-specific
|
||||
connector was found. Its [open-loop design](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/docs/guides/open-loops.md)
|
||||
informs requests, commitments, waiting and source freshness. Its
|
||||
[sync implementation](https://github.com/garrytan/gbrain/blob/e78f1c38b947b053f3a46881340f74f316be855a/src/core/connectors/sync.ts)
|
||||
advances progress after successful ingestion. Apply those principles in the
|
||||
external Codex workflow. The [publishing proposal](agent-publishing-design.md)
|
||||
covers its host scheduler, job execution and transactional write patterns.
|
||||
|
||||
### Rensheng / OpenBrief
|
||||
|
||||
Inspected local revision `c06c4e3f290800752a0c252c84fbca0eed61e45d`.
|
||||
Rensheng's [setup](https://github.com/yutakobayashidev/rensheng/blob/c06c4e3f290800752a0c252c84fbca0eed61e45d/docs/setup.md)
|
||||
reuses existing source tools. OpenBrief's
|
||||
[proposal-only MCP](https://github.com/yutakobayashidev/rensheng/blob/c06c4e3f290800752a0c252c84fbca0eed61e45d/crates/openbrief-app/src/mcp.rs)
|
||||
and [snapshot transport design](https://github.com/yutakobayashidev/rensheng/blob/c06c4e3f290800752a0c252c84fbca0eed61e45d/docs/adr/0004-separate-acp-local-and-remote-transports.md)
|
||||
are useful boundaries. Neither requires adopting its Rust application or
|
||||
duplicating its filesystem workflow in this app.
|
||||
|
||||
### Beeper Copilot
|
||||
|
||||
The [LP](https://beeper-copilot-lp.vercel.app/) was inspected in Chromium at
|
||||
desktop/mobile sizes. The three-pane view, person context, evidence chips and
|
||||
reply review are concrete UI references, documented in the
|
||||
[capture gallery](references/beeper-copilot/README.md). Its linked source repository
|
||||
returned 404 to unauthenticated access; screenshots verify the LP presentation,
|
||||
not backend behavior. Use life in the Scrapbox role. EventKit, macOS deployment
|
||||
and the demo's relationship scoring are not requirements here.
|
||||
|
||||
## Sending
|
||||
|
||||
The [send API](https://developers.beeper.com/desktop-api-reference/resources/messages/methods/send/)
|
||||
returns a pending ID, not delivery confirmation. Bind approval to exact draft
|
||||
revision, recipient and reply target, then resolve pending IDs before marking
|
||||
sent. The inspected schema does not document a client idempotency key, so local
|
||||
deduplication cannot guarantee exactly-once delivery after an ambiguous failure.
|
||||
|
||||
Disable automatic send retries and reconcile uncertain results. The
|
||||
[SDK defaults](https://github.com/beeper/desktop-api-js#retries) include retries on
|
||||
transport errors and timeouts. Publishing a draft/activity must not send a message.
|
||||
|
||||
The current [execution support](execution-support.md) is still fictional and
|
||||
in-memory. Establish the external agent's write interface and persistent typed
|
||||
activities before installing scheduled automation.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Beeper Copilot UI reference captures
|
||||
|
||||
Source: <https://beeper-copilot-lp.vercel.app/>
|
||||
|
||||
Captured on 2026-09-28 with Chromium through agent-browser. These are screenshots
|
||||
of the public landing page and its animated UI demonstrations, not screenshots
|
||||
of a logged-in production application. Displayed people and conversations come
|
||||
from that page, not this user's Beeper account. Animations can show different
|
||||
stages between captures. No page contents were modified to create the images.
|
||||
|
||||
| Capture | Contents |
|
||||
| ---------------------------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| [Desktop three-pane](desktop-three-pane.png) | Conversation list, conversation body/composer, person context; 1440 × 720 viewport |
|
||||
| [Reply review](desktop-reply-review.png) | Three reply styles, selected candidate, approval button; 1440 × 1080 |
|
||||
| [CRM and evidence](desktop-crm.png) | Person panel, evidence-backed fields, people board; 1440 × 1080 |
|
||||
| [Features](desktop-features.png) | Unified inbox, ghost completion, review and reply suggestions; 1440 × 1080 |
|
||||
| [Feedback](desktop-feedback.png) | Candidate comparison and writing-rule feedback; 1440 × 1080 |
|
||||
| [Desktop hero](desktop-hero.png) | Landing-page introduction and part of the demo; 1440 × 1080 |
|
||||
| [Desktop full page](desktop-full.png) | Entire landing page at 1440px wide |
|
||||
| [Mobile hero](mobile-hero.png) | Landing-page layout at 390 × 844 |
|
||||
| [Mobile conversation](mobile-conversation.png) | The demo's compressed conversation layout at 390 × 844 |
|
||||
|
||||
## Patterns to reuse
|
||||
|
||||
- Three coordinated panes: compact list, a dominant conversation, and persistent
|
||||
person context. In this app the right pane should show Codex-published life
|
||||
context, source references and pending user corrections.
|
||||
- Compact network badges on identities and messages. Keep original conversation
|
||||
identity available even when presenting a person across networks.
|
||||
- A reply review sits near the conversation and composer. Candidate selection,
|
||||
editing and confirmation remain visible steps; approval is distinct from
|
||||
generating or inserting a suggestion.
|
||||
- Evidence chips next to contextual statements provide a path back to messages
|
||||
or the published life source reference.
|
||||
- Suggested actions include their reason and can populate the appropriate
|
||||
editor. The app can render externally produced suggestions without inference.
|
||||
|
||||
The LP's dense right panel and desktop three-pane arrangement are useful
|
||||
references. Its mobile demo squeezes the columns and is not a good mobile
|
||||
navigation model for this app: use list → conversation with an accessible context
|
||||
panel instead. The LP's relationship-phase labels, coverage scores and confidence
|
||||
percentages are demo product choices, not requirements for this personal CRM.
|
||||
|
||||
For Home, borrow the contextual presentation inside a reply activity rather than
|
||||
embedding the full inbox. Weight logging needs a numeric input; a routine needs
|
||||
steps; an optional task needs a simple completion control. These can coexist in
|
||||
one activity list without forcing every activity into a chat layout.
|
||||
|
||||
See [external agent publishing](../../agent-publishing-design.md) for the proposed
|
||||
producer/consumer boundary and typed activity contract.
|
||||
|
After Width: | Height: | Size: 282 KiB |
|
After Width: | Height: | Size: 342 KiB |
|
After Width: | Height: | Size: 275 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 322 KiB |
|
After Width: | Height: | Size: 365 KiB |
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 158 KiB |