Skip to content

Refresh verification recipes and restore CI - #284

Open
tella-butler wants to merge 71 commits into
mainfrom
auto-daily-verification-skill-maintenance-202609020600
Open

tella-butler wants to merge 71 commits into
mainfrom
auto-daily-verification-skill-maintenance-202609020600

Conversation

@tella-butler

@tella-butler tella-butler commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • update session and new-session selectors to match current accessibility roles
  • make archived-session verification create its own disposable prerequisite and run phone coverage before restore
  • document the current phone settings dialog and back action
  • update vulnerable root and Electron transitive dependencies
  • include Kent's CI repairs from Make main CI green again: rootless gateway control socket, stale CI assertions, host-bound test #308 for the rootless gateway socket, host-independent webhook test, installer diagnostics, and transcript browser checks

Verification

  • completed source review and one isolated live pass across sessions/transcripts, automations, goals, archived sessions, and settings at desktop and phone widths
  • re-ran the corrected recipes against verify-20260902-060134-1065969
  • bun run check
  • root and Electron bun audit --audit-level=high
  • bun run test:transcript-scroll
  • gateway supervisor and PR webhook unit tests

Product gaps found

  • bks-demo-pr shows No transcript available for this session even though the demo fixture supplies transcript lines
  • the phone archived-row Restore button did not clear the archived state; desktop Restore session did

Started by Jaap Frolich in this OS session

@open-session-os-tella-dev

open-session-os-tella-dev Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🤖 OS review · request changes · confidence 2/5

Safe once the archive recipe ordering is fixed. The selector updates match the current UI, but the revised flow restores its only archived fixture before the required phone verification, making that portion impossible to complete.
1 inline comment below.

💡 Labels: os-auto-fix — I fix these and push until CI passes · os-adversarial — deeper two-pass review · os-simplify — quality cleanup pass.
Reviewed 6c07ac2 · GPT-5.6 Sol · earlier reviews collapse above · open session

🔁 Not merge-ready and no live session owns this branch — add the os-auto-fix label and I'll fix the findings automatically.

@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
opensession Ready Ready Preview Sep 3, 2026 1:18pm UTC

@open-session-os-tella-dev open-session-os-tella-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OS review · 6c07ac2

- **Clear and filter.** Refill the searchbox with an empty value, choose the `Filters` button using the exact accessible name from the current snapshot, and select one visible repository or person. Capture the filter state and narrowed result list.
- **Open a result.** Choose the button whose name starts with `Instrument request tracing in api-gateway`. Its transcript opens and keeps the archived state visible.
- **Restore.** From `/archived`, choose `Restore session` on desktop or `Restore` on phone. Confirm it disappears from `/api/sessions?archived=only&slim=1` and reappears in its active workspace.
- **Check phone layout.** Repeat search and result opening at 390x844. Select `Everyone` again because reopening the route resets the owner filter. Search and filters must remain reachable without desktop hover.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 P1 — Run the phone check before restoring the sole archived session

The recipe creates exactly one archived result, then the preceding Restore step removes it from the archived slice. Executing the bullets in order therefore reaches this phone step with no Instrument request tracing in api-gateway row to search for or open, so the required phone verification cannot run. This also contradicts the new gotcha that says to restore last. Move the restore step after the phone layout check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b393351: the recipe now runs the phone archive check before restoring its only archived result.

jfrolich and others added 25 commits September 2, 2026 07:26
The browser regression now carries the instrument that found the last
two bugs. An in-page probe, installed before the fixture loads, records
every programmatic scroll write with its stack and real effect, every
scroll and gesture event, every animation or transition inside the
scroller, and one sample per frame of the entry at the viewport top.
Between the settle points the regression asserts that this entry moves
only by what the reader scrolled, that no two writers cancel each other
inside one frame, that rows never transition their geometry, and that
hydrated history never fades in. Those were exactly the wobble and the
interrupted-scroll classes a trace had to be read to see.

Two shapes from production join the fixture: a reply taller than a
phone viewport measured for the first time, and growth above the reader
that is not a keyed prepend, inside their own row and in the row above,
through a new grow control. On the phone a touch fling toward history
gets growth above the reader while momentum runs: the correction must
wait for the momentum, land exactly, and never cancel the fling.

The adapter's source-string tests are gone; the regression is the
behavioral contract and the unit tests keep the pure helpers.
Reuse the headless Chrome and fixture server of the motion budgets step.
* Re-enable sandbox automations on disposable Executors

* Add thinking message visibility preference

* Support custom OpenAI-compatible providers with catalogs and discovery (#273)

* Support custom OpenAI-compatible providers with catalogs and discovery

A provider id unknown to Pi and Open Session runs when its config declares
api: openai-completions with a base URL, the same shape Wafer is injected
with. Per-model catalog rows (inline, catalogFile, or discovered) override
the conservative 131072/32768 stub, and an opt-in GET /v1/models poll fills
picker ids without removing operator-pinned ones. Settings writes preserve
the fields the form does not edit.

Refs #241

* Fix custom provider review findings

* Preserve case-sensitive provider model ids

---------

Co-authored-by: Michiel Westerbeek <[email protected]>

* Surface GitHub App installations in the repo picker (#271)

Installing the workspace App on a second account (for example an
organization, after onboarding pinned installationOwner to the personal
account that created the App) left the Add repository picker silently
empty: the pinned installation saw no repositories, nothing revealed that
the App was installed elsewhere, and the only way out was hand-editing
config.json.

- github-app.ts: listGithubAppInstallations() lists every account the App
  is installed on with the App JWT alone, so it answers even when the
  pinned owner matches no installation. Briefly cached.
- GET /api/setup/github/repos carries installationOwner and the
  installation list (with the selected one marked) alongside the repos,
  and includes the configured owner in the repo-list cache key so
  switching owners does not serve the previous installation's list for
  the TTL.
- The Add repository picker offers an installation switcher when the App
  is installed on more than one account (PUT /api/setup/github applies
  live), explains an empty installation instead of a bare 'No
  repositories match.', and offers one-click pinning when the configured
  owner matches none of them.

Refs #242

* Keep pi Claude sessions on the account holding their SDK conversation

Every pi Claude request re-picked an account, and the least-used tiebreak
round-robins equal accounts, so a session hopped subscriptions on nearly
every step. The stored SDK session is tagged with the account whose
config dir owns it, so each hop replayed the full context onto a fresh
SDK session (a prompt cache write, not a read) and burned limits on all
subscriptions evenly.

Pass the stored session's account as stickyId through pickBridgeAccount
into resolveAccount's existing sticky step. Pins, exhaustion, sidelining,
and the in-turn walk still move the session off it.

* Own the transcript reader anchor at commit time

Capture the entry at the viewport top in getSnapshotBeforeUpdate, the
instant before the DOM changes, and settle it after the commit as a delta
on the current scroll position. The previous restore replayed an absolute
viewport captured on an earlier scroll event, which undid reader movement
and fought TanStack's own compensation inside one commit (+358/-358 and
+5145/-5145 pairs in a live trace).

A virtualizer scroll write now commits its moved rows in the same frame,
and corrections defer while a touch or its momentum is in flight.

Drop the permanent transform transition on trailing rows: positions are
compensated by instant scroll writes, so a 200ms glide against them read
as the transcript wobbling on its own. Tail growth below a reader who
left the live edge now appears beneath them with no scroll write.

* Give the reader anchor sole ownership of its commit

While an anchor is held, TanStack's size-based measurement compensation
stands down: the settle after the commit restores the entry at the
viewport top from the DOM itself. A live trace showed the guess (a
spanning row's first measurement) being undone by that settle in the
same frame, two writes where one is enough.

* Fix disposable automation resumes

---------

Co-authored-by: Michael <[email protected]>
Co-authored-by: Jaap Frolich <[email protected]>
Meridian's early-stop tracker only counts mcp__oc__* calls as
client-forwarded. When the model emits a mangled name such as
mcp__ocuser__bash (seen live on Fable 5.1), the SDK answers "No such
tool available" without running PreToolUse, the visible turn never
settles, and with maxTurns=1 the query ends with nothing captured: the
run fails with "Reached maximum number of turns (1)".

Capture those tool_use blocks into the tracker and the forwarded list
after noteAssistantMessage. The SDK's error result then settles the
checkpoint and pi answers the unknown name with its own "Tool X not
found" result, so the model gets to retry like it would in Claude Code.
ToolSearch stays SDK-internal.
* Surface GitHub App installations in the repo picker

Installing the workspace App on a second account (for example an
organization, after onboarding pinned installationOwner to the personal
account that created the App) left the Add repository picker silently
empty: the pinned installation saw no repositories, nothing revealed that
the App was installed elsewhere, and the only way out was hand-editing
config.json.

- github-app.ts: listGithubAppInstallations() lists every account the App
  is installed on with the App JWT alone, so it answers even when the
  pinned owner matches no installation. Briefly cached.
- GET /api/setup/github/repos carries installationOwner and the
  installation list (with the selected one marked) alongside the repos,
  and includes the configured owner in the repo-list cache key so
  switching owners does not serve the previous installation's list for
  the TTL.
- The Add repository picker offers an installation switcher when the App
  is installed on more than one account (PUT /api/setup/github applies
  live), explains an empty installation instead of a bare 'No
  repositories match.', and offers one-click pinning when the configured
  owner matches none of them.

Refs #242

* Use every GitHub App installation

* Import organization members through that organization's installation
* Refine archived session hierarchy

* Align archive controls in the top bar
* Require Tella-issued editor fixture leases

* Verify Tella editor leases server-side

* Use verified creator login for Tella grants

* Close editor lease enforcement gaps

* Keep Tella fixture identity consistent

* Canonicalize editor preview routes

* Preserve delegated creator identity

* Source creator identity from trusted callers

* Preserve identity for authenticated task sessions
Thinking rows were filtered per transcript and rendered in place, so the
newest thought could sit above later tool calls. Arrange thinking per work
rail instead: with "latest" the newest thought of a live turn follows its
last step as a status and disappears once the turn settles; "all" keeps
every thought where it happened; "none" shows nothing. The collapsed live
rail header shows the current thought or last tool as its activity.
A bash call that starts with `cd <dir> && …` only sets up its working
directory; the row's one-liner now shows the command that follows.
The expanded view still carries the full text. Applied in the shared
protocol derivation (web, phone web) and the native Swift summary.
Keep child sessions nested for inventory purposes, but render a row only when the child owns a workspace or worktree. Distinct linked pull requests retain their status icon; the root workspace's PR is not repeated on child rows.
A create whose workspace, credential or branch effects ran long was
invisible for minutes: the session file was written only inside the
opening effect, after those effects settled, so the web shell was the
only copy of the session and its prompt.

Persist and announce the session as soon as its create dispatch and
setup plan are durable, before the git work, in the one path every
adapter and boot recovery share. Hold the session busy until the
opening turn takes run admission, so a prompt sent meanwhile queues
instead of starting a turn in a worktree that does not exist yet, and
list it as running. A setup failure after the announce lands on the
visible session and retires its dispatch instead of leaving a busy,
empty row.

Both adapters now share one actor-backed materializer with a
ten-minute backstop: the projected session no longer relies on the
client replaying its create to drive preparation.
jfrolich and others added 5 commits September 3, 2026 09:54
The tellahq installation hit its hourly GraphQL limit about once a day.
Nearly all of the spend was pr-info's `gh pr view <branch>`: gh resolves
a branch by wrapping the whole field set in `pullRequests(headRefName:,
first: 30)`, and with `commits` (100 x 100 authors) GitHub prices that at
32 points. The same fields by number cost 1. CI webhook bursts made it
worse: every check_run, status and workflow_run delivery dropped the
detail cache and broadcast pr_updated, so open tabs re-read the PR once
per delivery for as long as a pipeline ran.

- pr-info: resolve the branch to a number first (bulk cache, then a memo
  seeded from the durable snapshot, then a one-point lookup) and view by
  number. A memoized number is verified against headRefName once.
- pr-webhook: fold CI deliveries per branch into one refresh per 30s
  window, invalidating at broadcast time. PR, review, comment and push
  deliveries still refresh promptly.
- github-budget: report the bucket as consumers' own GraphQL responses
  see it (rateLimit is free to request), next to a probe that resolves
  its token through the same service credential path. The old probe
  logged used=0 through every exhaustion.
jfrolich and others added 7 commits September 3, 2026 11:11
A chip's text is folded into the prompt verbatim, so pasting a few
megabytes put the whole block in context and the turn failed before the
model saw a word of it: "Prompt is too long" on a single exchange, which
compaction cannot shorten.

Past 200k characters (about 50k tokens) the web composer now stages the
paste as pasted-text.txt through the same upload path a dropped file
takes. The agent gets the usual attached-file note and reads it with its
tools; the transcript shows the file chip and a download. Below the line
a paste still collapses into a chip, and a team note keeps the chip at
any size because it has no file channel.

Started by Michiel Westerbeek in this OS session:
https://os.tella.dev/session/os-01a0671c-d75e-79c1-bd39-3f19f3713358
A distill timer used to wait in-handler on a process-wide serial queue,
holding one of the shared kernel timer slots for the whole wait plus the
model call. Many sessions going idle together could occupy every slot and
delay scheduled prompts, agent waits, and ask escalations. The handler now
tries to take the single distill slot; when it is taken it replaces its own
timer 15-30s out and returns immediately.
jfrolich and others added 13 commits September 3, 2026 12:38
Local main fell 20 commits behind origin/main because git pull --ff-only
refuses the shared checkout as soon as one dirty file overlaps an upstream
commit, and nobody may discard another session's edit. Sessions then
rebased only their own commit or committed from a throwaway worktree, and
the shared branch drifted for everyone; 44 of the 61 blocking files were
byte-identical to origin/main, residue of edits that had already landed.

scripts/shared-checkout-sync.ts fast-forwards main in place: clean paths
follow upstream, edits that already landed become clean, genuine edits are
three-way merged onto the new base (index and worktree separately, with a
pre-merge copy under .git/shared-checkout-sync/), conflicts are left
untouched and listed, and the ref moves last by compare-and-swap. AGENTS.md
now makes it the only sanctioned way to move main, requires it at task start
and after every push, and forbids the worktree and rebase-only workarounds.
The skill is now written against the pinned [email protected] rather
than the early v4 beta the upstream (joelhooks/effectts-skills, MIT)
targeted, and it carries an Open Session-specific reference for the
frontend lifecycle runtimes. Allowlist it next to the other tracked
skills and ignore .agent-sources/, the source mirror it asks agents to
clone for API lookups.
Add the hosted Braintrust MCP (https://api.braintrust.dev/mcp, bearer API
key header) to mcp-config.example.json and the MCP-only integrations
section of the setup docs.

Started by Michiel Westerbeek in this OS session:
https://os.tella.dev/session/os-01a06762-a6ea-70a4-a59c-c70fc533c2b1
Install (ubuntu-latest) has failed on every main run since 2026-08-28
with only "the server did not start at http://127.0.0.1:3850" and a hint
to run `opensession logs`, which nobody can do on a finished runner. On
failure, dump the state and journal of every user unit the installer
created, the listeners, the health probe, and the log files, so the log
says why the service did not come up.
The supervisor bound its control socket at the fixed
/run/opensession-gateway/control.sock. That directory is what
RuntimeDirectory= creates for the system service; a rootless user
install gets $XDG_RUNTIME_DIR/opensession-gateway instead, so the user
unit died at boot with ENOENT on every start, the socket unit kept 3850
open with nothing behind it, and the installer reported a server that
never came up. This is what has failed Install (ubuntu-latest) on every
main run since 2026-08-28.

Derive the path from RUNTIME_DIRECTORY, which systemd sets for both
scopes, keeping the fixed path as the fallback outside systemd and the
explicit OPENSESSION_GATEWAY_CONTROL_SOCKET override on top.
reviewerRemovalClearsSessionRequest resolves the request's first name to
a GitHub login through the roster, which user-mappings bakes from this
host's config at module load. The test assumed a host where "Kent" maps
to kentdebruin, so it passed on the instance and failed on every CI run
since it landed. Seed a fixture roster the way the analytics tests do.

(cherry picked from commit 82a3b70)
Two more stale spots in CI that main's earlier failures had been hiding:

The transcript motion step polled only the fixture server, then handed
CDP_PORT to a fuzz tool that dials once and does not retry, so a Chrome
that was still starting on a cold runner failed the step with a
ConnectionRefused and no Chrome log. Poll the debugging port as well,
and print Chrome's and the fixture's logs when the step fails.

The installer job's service-definition check still looked for the
pre-supervisor ExecStart, so once the user service actually booted the
job fell over on that assertion instead. Accept the supervisor entry.
Mid-fling on the phone viewport the probe lands on a range placeholder
rather than a mounted entry, and its anchor id is `range:` plus the id
of the entry that opens the range. turnOf() only knew bare hydration
ids, so the mobile pass asserted "no fixture entry far enough above the
reader" on every CI run since the check was added. Accept the prefix:
the range starts at that turn, which is what a reader parked there sees.
@tella-butler tella-butler changed the title Refresh Open Session verification recipes Refresh verification recipes and restore CI Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants