ConnectOnionBack to Docs

ConnectOnion design journal

Engineering notes from the messy middle.

Concrete decisions, failed assumptions, and verified lessons from building Python AI agents, remote browsers, permissions, and release systems.

157

published field notes

Follow via RSS

Latest

Start with what changed recently

Archive

Find the decision behind the code

157 notes

  1. 3 min read

    A first run must finish its map

    Why co rem's first run works through every eligible page in its 90-day map, and how model access and nightly health stay visible when work cannot finish.

    REMMemoryProduct designReliability
  2. 2 min read

    The mailbox that failed at the end

    A lifetime scan can read thousands of mail headers and still fail on its last provider request.

    Email
  3. 2 min read

    Three matches, zero retained evaluations

    A REM Skill can have three coding-session name matches and zero retained evaluation attempts; the reader should explain both counts where they appear.

    REMDesignEvidence
  4. 2 min read

    A citation needs a thumb-sized door

    A Skill finding needs a direct source link that is easy to use on a phone, without hiding the full memory or its limits.

    REMDesignEvidence
  5. 2 min read

    The source is open, but the passage is far away

    A long Skill run source needs a way to reach the cited words without losing the archived excerpt or its limits.

    REMDesignEvidence
  6. 2 min read

    A purpose needs its evidence

    A Project card should say what the work is, and a clipped detail preview should keep each cited original reachable without making the reader hunt.

    REMDesignEvidence
  7. 2 min read

    A line break can be evidence

    A source can keep every word yet lose its meaning when HTML fields become one line. An Outlook rendering fix keeps the boundaries that help a reader verify a claim.

    REMEvidenceMail
  8. 2 min read

    The source link was one scroll too late

    The source link worked, but four of five written REM pages hid part of it below a phone's first screen. A small layout change moved evidence beside the claim it supports.

    REMDesignEvidence
  9. 2 min read

    A date is not a relationship origin

    A Person memory turned the earliest retained reply into first contact and a booking time zone into a person's. Both citations opened, but neither proved the claim.

    REMMemoryDesign
  10. 2 min read

    A folder is a route, not a proof

    A Project memory needs both its user's words and the reason those words were filed under that project. Neither alone proves work was completed.

    REMMemoryDesign
  11. 2 min read

    A Skill page must open its work

    A Skill memory summarized output that its sources and links could not show. We made the evidence openable and kept intended behavior separate from observed work.

    REMMemoryDesign
  12. 2 min read

    A window that survived the command

    One REM page reread the same coding sessions each time the CLI restarted. A local parsed window cut a repeat source pass from 103.5 to 2.1 seconds without hiding new input.

    REMPerformanceDesign
  13. 2 min read

    The mailbox that was there

    The first lifetime REM estimate found people in Outlook and none in Gmail. The Gmail account was connected, but the request for its own address waited thirty seconds and…

    TestingEmail
  14. 2 min read

    The people below the fold

    REM finally found the owner's older contacts. The People page said there were of them, but offered no way to reach them from that first screen.

    Remote BrowserReleaseTesting
  15. 3 min read

    The people outside the memory

    The owner looked at a new REM notebook and asked where everyone was. The first five-day trial had been narrowed further for a page test: --first-people 0 meant it wrote…

    Remote BrowserPermissionsTesting
  16. 2 min read

    A map needs a next step

    A real first-run map put the next action below the phone's first screen. We moved investigation into reach and made mapped Project leads honest about what remains unknown.

    REMMemoryRelease
  17. 2 min read

    Give the investigator the sources it needs

    The a28 REM investigation now searches supplied archives and live project files, with source trails that make its claims checkable.

    REMMemoryDesign Journal
  18. 3 min read

    Opening a written notebook

    A REM notebook with written pages took 42 seconds to reopen. We traced repeated relationship searches and PDF previews, then kept the same reader output with less work.

    REMMemoryDesign Journal
  19. 2 min read

    The project page that borrowed a reply

    A project page cited a reply from another project. We traced the source, narrowed attribution, and made Unknown visible when evidence ran out.

    REMMemoryDesign Journal
  20. 2 min read

    A memory page should open where the decision is

    The first REM reader made a familiar mistake. It took a good Markdown notebook and displayed each record like a long article.

    Remote BrowserTestingRuntime
  21. 2 min read

    The first memory was a request

    The first time the owner opened REM after init, the page looked like it had done its homework.

    TestingRuntime
  22. 2 min read

    The first run should remember something

    The early REM first run mapped a mailbox and local coding sessions into pages, then left most pages as empty frames.

    TestingEmail
  23. 2 min read

    The last request is not an insight

    On a first run, REM wrote a project page with three neat Insight bullets. They said what the owner had asked for, what the owner said had been published, and what the…

    TestingRuntime
  24. 2 min read

    The name stopped at the URL

    The owner remembered a pull request that renamed Wiki and asked whether it had reached the latest preview.

    Remote BrowserReleaseTesting
  25. 2 min read

    The nine projects that arrived after the map

    REM had already told its owner what it found. A first run mapped four projects, printed that count, and then started gathering the owner's coding-session messages so it…

    Release
  26. 2 min read

    The reader kept another name

    An independent review of rendered co rem pages found inconsistent reader labels, bookmarks opening Contents, and a mobile popup over preview commands.

    TestingUXNaming
  27. 2 min read

    It told me it had read 46 things

    I opened REM's invented test notebook with a question about Mara. The first thing it told me was that the night pass had read 46 items and rewritten four pages.

    Testing
  28. 3 min read

    The page that read five months

    Update, 2 October 2026: this records the earlier whole-notebook experiment. The current first-run decision selects recent important people, active projects and related…

    TestingWork RoomsEmail
  29. 3 min read

    An ID before a session

    Why Claude SessionStart supplies an ID before a resumable transcript exists, and how OIP handover and ACKs handle the first browser turn.

    Work RoomsClaude CodeReliability
  30. 2 min read

    The approval the browser could not see

    Trace a real Claude Code approval deadlock from a blocking Hook to an OIP lifecycle event, then verify the browser decision with Haiku.

    PermissionsWork RoomsClaude Code
  31. 3 min read

    The file changed. Why didn't the agent wake up?

    Historical note: This article describes the 1.8.9b9 Host watch preview. The implementation was removed in 1.8.9b12; Agent-owned session watches are tracked in #1788.

    AgentsWatchersArchitecture
  32. 3 min read

    The offline agent needed files

    On Friday, the Wiki's unattended maintenance run asked Luna to organize a batch it had already collected.

    Personal WikiAI AgentsReliability
  33. 2 min read

    The skill that stayed after its publisher withdrew it

    A publisher removed a skill and a subscriber ran co sub sync again. The command finished, but the skill was still on the subscriber's machine.

    Remote BrowserReleaseTesting
  34. 2 min read

    One Wiki, one folder in Codex

    The owner opened Codex's remote history to see what the Wiki had done. Instead of one Wiki, it showed a procession of folders named after individual runs.

    Remote BrowserReleaseTesting
  35. 3 min read

    Help should get you to the next command

    Update 2026-10-02: In the current co rem preview, init maps sources and then investigates the owner and recent important people, projects, and organizations with a model…

    Remote BrowserPermissionsRelease
  36. 2 min read

    A correction is new evidence

    A project page says “launched.” Its owner corrects it: the project is still a prototype.

    ReleaseTesting
  37. 2 min read

    An empty map needs an explanation

    The user ran Wiki initialization, opened the reader, and found no people. They had already connected their mailbox.

    TestingEmailRuntime
  38. 2 min read

    Let initialization start

    The user ran co wiki init and reached two questions before seeing a map: may it read Gmail correspondent metadata, then may it read Outlook?

    TestingEmailAPI Design
  39. 3 min read

    Gmail kept the body and changed the ID

    A live Gmail test exposed rewritten Message-ID headers. A preserved attempt marker recovers send receipts without risking a duplicate email.

    Remote BrowserReleaseTesting
  40. 3 min read

    The command that blamed the wrong password

    On 27 August, four emails were queued in Outlook for the next morning. An hour later the wording had to change.

    Remote BrowserPermissionsRelease
  41. 4 min read

    The Command That Had to Run on a Broken File

    Draft for 1.8.4; publish after release acceptance.

    Remote BrowserReleaseTesting
  42. 2 min read

    The suite was green and a thread was spinning

    The test named in the timeout was a scroll test. Running it alone did not explain why the complete Linux suite kept stopping there.

    Remote BrowserTestingDeployment
  43. 6 min read

    The request ended. The copy did not.

    The copy test lost its connection just after the NAS returned a task ID. The client had reached its waiting limit. The NAS still had a job to do.

    Remote BrowserReleaseTesting
  44. 2 min read

    The draft that was still number one

    The agent had just listed Gmail drafts. Its next command used a number, as the CLI invited it to do.

    Remote BrowserTesting
  45. 3 min read

    The refresh token we already had

    “Why does YouTube need a database migration?”

    Remote BrowserPermissionsRelease
  46. 2 min read

    A browser on a server, using your address

    Use co proxy share to authorize one remote agent to browse through your computer's internet connection; review latency and network limits.

    Remote BrowserPermissionsRelease
  47. 2 min read

    A reason that nothing read

    Check terminal_reason before browser operations so expired, revoked, or unpaid sessions cannot keep serving pages.

    Remote BrowserTestingRuntime
  48. 2 min read

    Bind first, then prepare

    Acquire the daemon socket lock before preparing shared credentials so a losing startup cannot delete the winner's files.

    Remote BrowserTestingRuntime
  49. 3 min read

    The suffix list, and the table that checked itself

    Audit special-use hostname suffixes and test destination policies against independent fixtures and deliberate mutations.

    Remote BrowserTesting
  50. 3 min read

    The wall was the hard part, not the pipe

    Route a server browser through a home connection while refusing private-network destinations such as 192.168.0.1.

    Remote BrowserReleaseTesting
  51. 4 min read

    Every test was green and the feature had never worked once

    Run native egress preflight through the real browser driver and verify that forbidden destinations actually reach the denying gateway.

    Remote BrowserReleaseTesting
  52. 3 min read

    The check and the browser read different names

    Align URL policy checks with browser parsing and test generator-based deny ranges inside IPv4-mapped IPv6 addresses.

    Remote BrowserReleaseTesting
  53. 4 min read

    The gateway held, but the answer leaked

    Inspect client-facing proxy responses as well as outbound destination checks to expose response-smuggling gaps in egress tests.

    Remote BrowserReleaseTesting
  54. 2 min read

    One Daemon, Many Conversations

    Remove daemon-wide request serialization so a long browser task does not block independent sessions; preserve ordering within each session.

    Remote BrowserTestingRuntime
  55. 2 min read

    127.0.0.1 did not look like an IP address

    Normalize numeric hostnames such as 2130706433 before applying private-address policy so the browser and validator agree.

    Remote BrowserSecurityChromiumSsrf
  56. 3 min read

    A Private Tab Is Not a Private Browser

    Give remote browsing exclusive process, profile, proxy, and socket ownership; owner-bound tabs alone cannot isolate network authority.

    Remote BrowserTestingRuntime
  57. 3 min read

    A Session ID Is Not Browser Authority

    Bind browser operations to the authenticated owner and lifecycle so a session identifier alone cannot grant access after reconnect.

    Remote BrowserTestingRuntime
  58. 3 min read

    A Thread Is Not an Async Runtime

    Replace a shared blocking worker with owned async execution so separate browser sessions can make progress concurrently.

    Remote BrowserReleaseTesting
  59. 2 min read

    Focus Before Delete

    Check that focus reached the intended editor before select-all and delete, preventing successful commands from clearing the wrong content.

    Remote BrowserTestingRuntime
  60. 3 min read

    Input Was the Uncancellable Part

    Move cancellation to the terminal-input boundary so stopping wait_for_manual_login does not leave a worker waiting for input.

    Remote BrowserReleaseTesting
  61. 2 min read

    Sleep Was the Global Lock

    Make humanized typing and pointer timing awaitable so one tab's simulated input does not freeze another tab.

    Remote BrowserReleaseTesting
  62. 3 min read

    The Browser Opened Before We Knew It Was Safe

    Require a browser preflight after launch to prove proxy refusal and network isolation before declaring a private browser ready.

    Remote BrowserPermissionsRelease
  63. 3 min read

    The browser worked until the caller already had a loop

    Keep synchronous Browser methods over one owned event loop, with explicit thread ownership and shutdown joining.

    Remote BrowserReleaseTesting
  64. 3 min read

    The command we had to send before the command

    Check the running daemon's engine before sending commands so a paid Onion browser request cannot silently use another engine.

    Remote BrowserReleaseTesting
  65. 2 min read

    The Matcher Left the Loop

    Move synchronous model-backed element matching off the browser event loop so unrelated tabs respond while a model is pending.

    Remote BrowserReleaseTesting
  66. 2 min read

    The paid launcher was on the wrong loop

    Expose an async Onionwright paid launcher for the Patchright event loop while preserving charge, renewal, expiry, and release ownership.

    Remote BrowserReleaseTesting
  67. 2 min read

    The proxy replied, but the 429 disappeared

    A proxy that closes with unread peer bytes can reset the socket on macOS; test that the client receives the overload response before closure.

    Remote BrowserProxySecurityTesting
  68. 3 min read

    The second tab was not concurrent

    Time simultaneous operations to distinguish tab isolation from concurrency, then move daemon and driver work onto one async runtime.

    Remote BrowserReleaseTesting
  69. 2 min read

    The Upload Button Was in Another Document

    Preserve frame routing and listener timing during async migration so file inputs in another document remain reachable.

    Remote BrowserReleaseTesting
  70. 4 min read

    The URL Passed, but the Socket Was Still Unknown

    Resolve, validate, and dial approved numeric addresses in the gateway; a URL check before page.goto cannot control later connections.

    Remote BrowserReleaseTesting
  71. 6 min read

    A Patch Must Move Forward

    Require a forward-port issue for each stable fix and resolve its applicability to every active newer release before publication.

    ReleaseCI
  72. 2 min read

    A Stable Candidate Cannot Ignore Late Evidence

    Stop stable promotion when unattended browser acceptance reveals a new failure; publish new immutable candidate bytes and repeat the gate.

    Remote BrowserPermissionsRelease
  73. 6 min read

    An Image Prefix Is Not an Image

    Validate complete data URLs and image payloads before upload so base64-looking text cannot enter the image path.

    ReliabilityTesting
  74. 6 min read

    co ai Delegates to Codex and Claude Code — and You Watch It Work

    ConnectOnion 1.7 adds resumable native coding Work Rooms, explicit permission modes, and live tool activity through co ai.

    ReleaseWork Rooms
  75. 6 min read

    Headless Does Not Mean Unconfigured

    Honor explicit command grants in unattended Auto while rejecting broad legacy wildcards that would authorize unlimited actions.

    PermissionsAutomation
  76. 2 min read

    One Fix, Every Newer Line

    The release contract checks Git ancestry and applicable behavioral fixes across supported branches, excluding old version metadata from forward-ports.

    Remote BrowserReleaseTesting
  77. 2 min read

    A Durable Downgrade Must Also Be Live

    Publish the narrowed provider lifecycle revision when Host permissions change so open Work Rooms immediately reflect stored authority.

    Remote BrowserPermissionsRelease
  78. 2 min read

    A new candidate needs a new name

    Use a new candidate version whenever published code changes so install commands, evidence, checksums, and rollback identify the same bytes.

    Remote BrowserReleaseTesting
  79. 2 min read

    A Permission Change Has One Public Truth

    Emit the final permission state after a downgrade so stopping and reopening native provider work cannot expose an intermediate authority.

    Remote BrowserPermissionsRelease
  80. 2 min read

    A permission is a complete state

    Copy both the validated mode and positive turns_left budget into native continuations; missing budgets degrade to Auto without renewing authority.

    Remote BrowserPermissionsRelease
  81. 2 min read

    A tool result is not a final answer

    Distinguish a successful Claude Code tool result from parent-turn completion so an empty model answer cannot strand the chat composer.

    Remote BrowserReleaseTesting
  82. 3 min read

    Arm the deadline before the tool returns

    Arm the parent model's 90-second settlement limit before provider work starts and recover the boundary from durable codex or claude_code traces.

    Remote BrowserPermissionsRelease
  83. 2 min read

    Auto must mean the same promise

    Translate Host Auto intent into each native provider's workspace controls while preserving the separately confirmed Full Access ceiling.

    PermissionsReleaseTesting
  84. 2 min read

    One Approval Boundary Is Enough

    Define one explicit handoff from Host policy to native provider approval so a managed delegation does not stall behind nested dialogs.

    PermissionsReleaseTesting
  85. 2 min read

    The daemon was not the slow part

    Measure the command path before blaming the daemon queue; avoid importing the entire persistent service for every state query.

    Remote BrowserReleaseTesting
  86. 2 min read

    The First Correct Snapshot Was Still Wrong

    Publish one provider snapshot at the final authority ceiling after Stop and downgrade, then verify reopened native sessions.

    Remote BrowserPermissionsRelease
  87. 3 min read

    The last change is the name

    Change package version and Production/Stable metadata together, run twine check, and switch docs only after PyPI serves the final package.

    Remote BrowserPermissionsRelease
  88. 2 min read

    The snapshot that arrived thirty-nine times

    Separate replacement snapshots from append-only events so repeated provider state cannot flood the chat and hide an approval.

    Remote BrowserPermissionsRelease
  89. 2 min read

    The tool finished but the turn did not

    Bound parent model settlement, retry once after a timeout, and end with an explicit error if the retry also expires.

    ReleaseTestingWork Rooms
  90. 2 min read

    The workspace default was already known

    Use the Host-owned workspace when a native coding call omits a directory, while rejecting requests outside the authorized boundary.

    PermissionsReleaseTesting
  91. 3 min read

    A Release Candidate Is a Testable Artifact

    Test a clean public wheel through real browser and provider journeys, and keep its bytes unchanged during release acceptance.

    Remote BrowserPermissionsRelease
  92. 2 min read

    The Work Room Needed Its Own Permissions

    Keep Host authority, provider-session modes, and individual approvals distinct and visible in the native coding client.

    Remote BrowserPermissionsRelease
  93. 6 min read

    What Makes an Agent 10x

    Design agents around verifiable work, durable time, learned experience, bounded delegation, and access to real tools.

    VisionReliability
  94. 2 min read

    A Snapshot Is Not Live State

    Update Control Center readiness from live running and approval events so a stored snapshot cannot label a busy agent available.

    Remote BrowserPermissionsRelease
  95. 2 min read

    A Transcript Is Not a Client

    Send new messages into the same native provider conversation so users can continue work from the remote client.

    Remote BrowserPermissionsRelease
  96. 2 min read

    A Workspace Boundary Is Not a Path

    Reject out-of-workspace provider requests without exposing private roots, missing paths, file names, or symlink targets in public errors.

    Remote BrowserPermissionsRelease
  97. 2 min read

    An Action Is Not a Reason

    Describe the operation being performed above a tool call and leave supporting evidence available without inventing model rationale.

    ReleaseTestingAPI Design
  98. 2 min read

    An Invite Is Not an Environment

    Pass co ai --invite-code for a local run or --invite-code-file for automation while keeping temporary credentials out of persistent configuration.

    Remote BrowserPermissionsRelease
  99. 2 min read

    The Approval Belonged to the Wrong Room

    Place native session decisions in the Work Room that can answer them so Host-level approval does not silently stall provider follow-ups.

    Remote BrowserPermissionsTesting
  100. 2 min read

    The Beta Caught the Wrong Question

    Change tool summaries from inferred reasons to observable actions so type-correct UI contracts do not encourage invented explanations.

    ReleaseTestingAPI Design
  101. 2 min read

    The Bill and the Counter Disagreed

    Use one source of truth for new, cached, and output-token accounting so the chat can explain the charge on a managed request.

    Remote BrowserTestingDeployment
  102. 2 min read

    The Timeout That Blocked Recovery

    Allow recovery actions after DOMContentLoaded times out instead of repeating the same blocked readiness check before every command.

    Remote BrowserReleaseTesting
  103. 2 min read

    The Workroom Lost the Conversation

    Carry provider requests and answers through the shared protocol so live status and tool summaries do not replace the conversation.

    Remote BrowserReleaseWork Rooms
  104. 2 min read

    A Mode Is Not a Compatibility Shim

    Reject legacy authority aliases rather than translating them into Auto, Read only, or Full Access permissions.

    Remote BrowserPermissionsWork Rooms
  105. 2 min read

    A URL Is One Piece of Data

    Render long co auth google URLs without inserted line breaks so headless users can copy the exact credential handoff value.

    Remote BrowserTestingDeployment
  106. 2 min read

    No Dialog Is Not Approval

    Apply the same outside-workspace and unknown-tool policy when no approval UI exists; missing dialogs must not grant authority.

    Remote BrowserPermissions
  107. 2 min read

    The Log Sent Us to the Wrong File

    Pass configuration provenance through deployment layers so invite diagnostics identify the actual source without exposing secrets.

    DeploymentRuntimeAPI Design
  108. 2 min read

    The pipeline that succeeded without doing the work

    Use a nonzero command outcome for unfinished agent work so shell pipelines cannot treat an exhausted iteration budget as success.

    TestingRuntime
  109. 2 min read

    Three Labels Were One Decision

    Map Host Auto, Read only, and Full Access to native provider settings so legacy Default and workspace labels cannot imply different authority.

    Remote BrowserPermissionsRelease
  110. 2 min read

    A Server Quota Is Not a Ceiling

    Expose server region choice from the backend catalog so regional GCE address quotas do not become a global provisioning ceiling.

    DeploymentAPI Design
  111. 3 min read

    Authorise in Advance, So Nobody Signs at 3am

    Separate connection-sharing authorization from tunnel transport and reject attempts by the proxy to authorize its own egress.

    Remote BrowserPermissionsTesting
  112. 2 min read

    New Feature Work Needs a New Number

    Move new remote-browser and server-region work to the next feature line while a frozen release accepts stabilization fixes only.

    Remote BrowserPermissionsRelease
  113. 2 min read

    Sharing a Mailbox Is Not the Same as Giving It Away

    Authorize another agent against an existing mailbox identity so outreach and CRM history stay attached to the original address.

    Remote BrowserPermissionsEmail
  114. 2 min read

    The Browser Gate Was Only Windows

    Run clean-wheel browser acceptance on each supported platform so Windows-only coverage cannot hide macOS daemon failures.

    Remote BrowserPermissionsRelease
  115. 2 min read

    The Model Was Holding the Browser

    Separate model waiting from the browser execution lane so spending-cap retries cannot freeze unrelated browser sessions.

    Remote BrowserReleaseTesting
  116. 6 min read

    Your Servers, Your Regions, Your Shared Mailboxes

    Release notes for server-region choice, shared mailboxes, collision-safe Outlook downloads, and bounded provider requests.

    ReleaseEmail
  117. 2 min read

    A Message Is Not Accepted Until Codex Accepts It

    Keep a follow-up draft until successful steering or native turn start; placing text in a Host queue is not delivery.

    Remote BrowserTestingWork Rooms
  118. 2 min read

    A Stop Request Is Not a Stop

    Distinguish Stop intent, delivery, and terminal outcome so the client reports cancellation only for the targeted provider invocation.

    Remote BrowserTestingWork Rooms
  119. 2 min read

    A Thumbnail Is Evidence, Not a Placeholder

    Render verified workspace or inline PNG evidence and reject outside paths, malformed bytes, and stale revisions.

    Remote BrowserPermissionsRelease
  120. 3 min read

    A Work Room Has One Writer

    Let the provider-owning layer emit lifecycle revisions and retain artifacts while browser consumers reject stale or malformed state.

    Remote BrowserPermissionsRelease
  121. 2 min read

    Auto Is a Boundary, Not a Bypass

    Allow narrow local workspace work without repeated approval while leaving ambiguous, destructive, and broader actions under review.

    Remote BrowserPermissionsRelease
  122. 6 min read

    The Work Room Is a Client, Not a Status Panel

    Keep provider conversation, follow-up input, lifecycle, and controls in one Work Room while the native adapter owns execution.

    Work RoomsOIP
  123. 3 min read

    A Name Is Not an Adapter

    Require a Codex tool card and an openable Work Room from the native provider path; pwd and which codex do not prove a Codex session started.

    Remote BrowserPermissionsRelease
  124. 3 min read

    A Session ID Is Not a Work Room

    Emit provider-owned identity, status, authority, continuation, and replay so a UUID inside a tool result becomes a usable Work Room.

    Remote BrowserPermissionsRelease
  125. 6 min read

    A Tool Transaction Is Not a Work Room

    Send live provider activity and approval events through OIP while keeping raw terminal detail out of the default chat surface.

    Work RoomsOIP
  126. 2 min read

    A User Message Is Not Always a String

    Extract text from structured user content without discarding image parts or calling string methods on a list.

    Remote BrowserRuntimeAPI Design
  127. 6 min read

    A Work Room Is a Summary, Not a Transcript

    Use a finite OIP Work Room summary with verified decisions and evidence instead of replaying raw terminal transcripts by default.

    Work RoomsOIP
  128. 6 min read

    An Approval Is Not Execution Time

    Exclude time spent waiting for an operator's approval from the active provider execution budget.

    PermissionsCodex
  129. 2 min read

    Stop Is a Process-Tree Operation

    Launch shell work in a process group, send SIGTERM on Stop or timeout, then SIGKILL after a grace period; revoke the IO lease to ignore late results.

    Remote BrowserTestingRuntime
  130. 3 min read

    The Long Tail of a Default

    Centralize DEFAULT_MODEL and audit examples, templates, and docs so an old model string does not survive as misleading guidance.

    Remote BrowserReleaseTesting
  131. 3 min read

    The Screenshot Was Not the Test

    Test screenshots alongside provider state, reconnect behavior, and operating-system resources to prove Stop and resume actually work.

    Remote BrowserPermissionsRelease
  132. 4 min read

    The Second Connection Was Still the First

    Preserve relay and session continuity across browser reloads while checking that identity and authority have not changed.

    Remote BrowserPermissionsRelease
  133. 2 min read

    A label is useful only when the work has somewhere to ship

    Classify contributions and require real release metadata so unlabeled work and placeholder milestones cannot disappear into the merge queue.

    Release
  134. 6 min read

    A Page Should Not Become a Wall

    Retrieve later mailbox pages with get_emails(last=1000, offset=2000) or co email inbox --last 1000 --offset 2000.

    EmailAPI Design
  135. 6 min read

    Changing the Default Model Is a Backend Decision First

    Verify backend support before clients request Gemini 3.7, and preserve explicit user model choices.

    ModelsRelease
  136. 3 min read

    Codex Was Ready. Codex Had Never Opened.

    Enforce requested provider identity across the browser protocol and validate the installed wheel so base-model fallback cannot fake a handoff.

    Remote BrowserPermissionsTesting
  137. 2 min read

    Evaluation Is a Choice

    Enable optional judging with co ai --eval; retain the newest 500 generated session records while keeping authored evaluation suites.

    TestingAPI Design
  138. 2 min read

    Every PR tells its story

    Require a docs/blog post through the blog-gate CI check so implemented capabilities ship with CLI help, user documentation, and engineering lessons.

    TestingAPI Design
  139. 6 min read

    One Browser Protocol, Native Coding Adapters

    Use one browser-facing protocol while native backend adapters retain provider sessions, approval behavior, and execution ownership.

    OIPArchitecture
  140. 4 min read

    One Default, Five Answers

    Replace repeated model strings with one DEFAULT_MODEL while preserving explicit user configuration and a documented rollback.

    Remote BrowserReleaseTesting
  141. 2 min read

    Ten minutes was not a timeout policy

    Stop silently capping caller timeouts at ten minutes and propagate real timeout errors through direct APIs and Agent traces.

    TestingRuntimeAPI Design
  142. 6 min read

    The Agent That Was Itself, and Billed Someone Else

    Control which credentials a deployed process inherits so operator configuration cannot silently replace agent identity or billing authority.

    SecurityDeployment
  143. 2 min read

    The cache was invisible

    Surface provider cached-token counts in local accounting and terminal output so repeated requests show their actual charge.

    Remote BrowserReleaseTesting
  144. 4 min read

    The CLI is the product

    Expose API features in CLI help and route email ownership failures to co email addresses so users can find a valid next command.

    ReleaseTestingEmail
  145. 6 min read

    The Owner Needs a Door

    Provide a private owner recovery path that permits initial agent access without leaking invite credentials into logs.

    SecurityOnboarding
  146. 2 min read

    The Third Argument Was Already Taken

    Preserve the reply method's existing positional arguments while adding attachment validation and regression tests for legacy callers.

    Remote BrowserReleaseTesting
  147. 2 min read

    When “Download” Quietly Meant “Replace”

    Allocate unique download paths for duplicate attachment names and existing local files, then return the paths actually written.

    Remote BrowserReleaseTesting
  148. 2 min read

    When logging looked like authoring

    Distinguish source authoring from command-output logging so append redirects and tee can write audit records without retry loops.

    Remote BrowserTestingRuntime
  149. 6 min read

    ConnectOnion 1.6.0

    Review the release's remote-agent controls and the separation of deployed agent credentials from operator identity.

    ReleaseSecurity
  150. 6 min read

    Auto-Debug Design Evolution

    Compare five debugging designs that reduced mode complexity and focused the workflow on inspecting live agent execution.

    DebuggingUX
  151. 6 min read

    Progressive Disclosure in CLI Design

    Scaffold a working agent project first, then reveal configuration choices when users need them instead of requiring a setup questionnaire.

    CLIUX
  152. 6 min read

    Why “Address” Beats “Identity”

    Use address for network routing and keep reputation, authorization, and broader identity concepts separate in the public API.

    API DesignNaming
  153. 6 min read

    Why Agent Addresses Use Hex-Encoded Ed25519 Keys

    Represent the full Ed25519 public key in hexadecimal with a 0x prefix so an address directly carries the agent's public verification key.

    SecurityNetwork
  154. 6 min read

    Why We Chose input() Over run()

    Send a task through Agent.input() so the primary method names the caller's input rather than exposing a generic execution verb.

    API DesignUX
  155. 6 min read

    Why We Chose llm_do() Over llm()

    Use llm_do() for a single LLM task without creating an Agent; the function name states an action rather than naming a model object.

    API DesignNaming
  156. 6 min read

    Why We Chose “Trust”

    Use trust as the public API concept for both accepting incoming agents and deciding which remote agents may be called.

    API DesignSecurity
  157. 6 min read

    Designing the ConnectOnion Network Protocol

    Compare agent addressing, messages, and direct connections with the earlier identity and session machinery.

    ArchitectureNetwork