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 |