Skip to content

v0.9.23: project files foundation, ci fixes - #9078

Merged
waleedlatif1 merged 11 commits into
mainfrom
staging
Oct 15, 2026
Merged

waleedlatif1 merged 11 commits into
mainfrom
staging

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

mzxchandra and others added 11 commits October 14, 2026 17:58
* feat(project-files): add rendered delivery and indexed search

* chore(files): shrink obsolete audit baselines

* fix(files): fence content delivery and preserve shared render caches

* fix(files): await delivery observers and track private CLI downloads

* fix(files): bound CSV previews and preserve render provenance

* fix(files): fence render names and separate compiler caches

* fix(files): align search with rendered cache identities

* test(files): guard required document format fixtures
* feat(project-files): add cross-owner copy and bulk transfers

* fix(files): satisfy bulk operation lint checks

* fix(files): harden bulk admission and staged publication

* fix(files): keep download input type module-local

* fix(files): recheck archive admission and hydrate copy paths once
… trim Project read transactions (#9063)

* fix(project-files): requeue rendered-artifact search after commit and trim Project read transactions

- Project artifact reads no longer requeue search inside the read transaction, which held the
  Project and source row shared and then needed them exclusively; the requeue runs after commit
  with its owner lock bounded by the short artifact-ready lock timeout and is best effort
- Artifact, inline, and CSV preview reads authorize from their own snapshots instead of a separate
  preflight; artifact inputs are snapshotted only when referenced and download with bounded
  concurrency after a declared-size budget check; the request signal reaches render and compile
- Project inline delivery streams and caches content-addressed key requests like workspace inline
- Project search admits, withholds previews, and reports provenance after its snapshot commits,
  classifies provenance only when a gate or delivery observer needs it, and lists folders directly
- A Project page embedding another owner's image is a missing input instead of a 500
- Page limits are shared from page-document.server; knip and the CI isolate build are tightened

* test(project-files): start requeue checks from no search revision
…runs out (#9060)

* fix(pii): load models only in workers and recycle them before memory runs out

The uvicorn supervisor imports the app before spawning workers, so the
module-level engine build left it holding an idle ninth copy of every model.
Engines now build in the FastAPI lifespan, which runs only in serving
processes. With more than one worker, each now exits after a jittered request
count and the supervisor respawns it, bounding per-worker memory growth that
otherwise reached the task limit about 11 days after a deploy.

* improvement(pii): move the start command into pii-entrypoint.sh and build engines in lifespan
…retention (#9061)

* chore(ci): tag production promotions with release-<sha> for rollback retention

* improvement(ci): share one promote-image script across repos
…ery (#9064)

* fix(files): restore workspace read-path behavior after rendered delivery

* fix(files): keep the delivery recheck for every principal and narrow the csv parser

* fix(files): keep the receipt recheck's provenance read typed for existing callers
* feat(project-files): add public sharing and protected delivery

* fix(project-files): align public sharing with current renderer contracts

* test(project-files): follow canonical inline cache policy

* fix(project-files): enforce public delivery and share policy safety

* test(project-files): explicitly retire fixture shares during teardown

* test(project-files): restore sharing suite environment
…r interrupted tool (#9059)

* fix(mothership): take over runs whose controller died and re-run their interrupted tool

A Chat run is driven by the Sim process that admitted it. When that process
stops mid-run (a deploy's old task set is terminated, or a crash) and no
browser is attached, nothing takes the run over: recovery only ran from a
browser reconnect, the in-flight tool's result was never recorded, and the
worker eventually ended the run as detached.

- Every Sim process now looks every 20s for interactive runs whose chat lock
  is gone and takes each over through the same recovery a reconnect runs,
  acting as the run's user under a delegated principal that re-checks that
  user's current access. The chat lock and controller token still admit
  exactly one controller, so a racing reconnect or another process loses.
- A user who lost access gets the run settled as an error and the worker is
  told to stop it.
- A Sim tool whose owner died before recording a result (its execution lease
  lapsed while the call was still running) is claimed again under a new owner
  token and run again, by the server for a workflow tool. Each start is
  counted; after three, the call fails with a clear message instead.
- A takeover waits while one of the run's Sim tools still holds its lease.

* fix(mothership): import the takeover by absolute path and regenerate the schema mock

* fix(mothership): page past live controllers, stop a scan on shutdown, dispose chat pubsub in tests

* test(mothership): assert the claim admits a first execution or an interrupted re-run

* test(mothership): add execution_attempts to the browser download fixture table

* fix(mothership): bound the takeover scan, stop earlier attempts' commands, decline takeovers on shutdown

- The abandoned-run scan resumes from a durable cursor and examines a bounded
  window per round, so runs whose controller is alive cannot hide later runs.
- A re-run's earlier attempts' workbench commands are handed to the
  workbench recovery to stop before the re-run may use the workbench; each
  recorded command now names the attempt that started it.
- Shutdown aborts a takeover still in flight at its controller claim.
- Only an authorization denial settles a run as revoked; other takeover
  failures leave it recoverable, as a failed reconnect does.
- The suite sets REDIS_URL only when a test Redis is configured.

* fix(mothership): keep the takeover stop handler module-private

* fix(mothership): let the server re-claim a workflow call its dead claimant never started

* fix(mothership): harden abandoned-run takeover

- Add the `mothership-abandoned-run-takeover-disabled` AppConfig kill switch,
  checked once per scan; off by default, so takeovers run unless it is on.
- Stop a controller whose chat lock lapsed while every renewal threw, so a
  controller partitioned from Redis cannot keep driving a run taken over.
- Never revoke another call awaiting its re-run from a sibling's wait or
  workbench access; the sibling's workbench access still stops that call's
  dead attempt's commands.
- Treat a workspace access loss found inside recovery like an authorization
  denial, by error type; other recovery failures stay recoverable.
- Cover organization Assistant takeover for a member and a removed member.

* fix(mothership): negate the re-runnable predicate without an optional SQL operand

* fix(mothership): time the lock lapse from its acquisition, type the re-run predicates as conditions, revoke access mid-recovery in the test

* test(mothership): find the attempt cap inside the typed re-run conjunction
…bles in docs markdown (#9066)

* improvement(api): publish an RFC 9727 API catalog and compact indented tables in docs markdown

* fix(docs): turn off table padding in the markdown serializer and assert exact catalog URLs
* fix(chat): retain resized panels when pointer capture ends

* fix(chat): handle native focus and touch resize gestures
@vercel

vercel Bot commented Oct 15, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 15, 2026 8:47am UTC

Request Review

@waleedlatif1
waleedlatif1 merged commit 595e62e into main Oct 15, 2026
99 checks passed
@greptile-apps

greptile-apps Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[High impact] Refactors file delivery and adds project-scoped file operations.

Fix the shared-image failure and satisfy the object-filtering rule before merging.

Findings

  1. P1 Shared images return 404 ▶
  2. P2 Object filter violates standards ▶

Summary

Adds Project file rendering, indexed search, cross-owner copies, bulk transfers, and protected public sharing. Also adds abandoned Chat run takeover, PII worker recycling, release tags, API discovery, and resize fixes.

  • Project files can be rendered, searched, previewed, exported, and unpacked.
  • Files and folder trees can move between Projects and workspaces.
  • Project files can be shared with public or gated access.
  • File delivery rechecks the file and access before returning its bytes.
  • Chat runs can resume after their controller stops responding.
  • PII models load inside workers that can be recycled before memory runs out.
  • Production image promotions keep a release tag for rollback retention.
  • The API publishes a machine-readable catalog at its well-known address.
  • Chat panel resizing keeps working through pointer and focus changes.
  • Generated lists and project checks track the new files and operations.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Request[File request] --> Authority[Check member access or share credentials]
  Authority --> Snapshot[Read current file and input revisions]
  Snapshot --> Bytes[Read or render bytes]
  Bytes --> Recheck[Recheck access and revisions]
  Recheck --> Delivery[Return file]
  Delivery --> Search[Requeue rendered search after commit]
Loading

Reviews (1) · Last reviewed commit: "fix(chat): preserve panel resize gesture..." · Reviewed by Greptile

Comment on lines +96 to +102
const resolved = resolveEmbeddedFileRef(
src,
owner,
typeof window === 'undefined' ? undefined : window.location.origin
)
if (resolved.kind === 'rejected') return undefined
return resolved.kind === 'file' ? `${inlineBase}?${inlineRefQuery(resolved.reference)}` : src

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 Shared images return 404

For shared Markdown containing a full same-origin image URL, resolveImageSrc now rewrites it to the token's inline route. That route checks the original Markdown through hasEmbeddedFileRef, which never supplies trustedOrigin and therefore rejects the absolute URL. The image returns 404, even for a signed-in reader who could previously load its private URL.

Give the browser and server the same trusted-origin rules without accepting foreign origins.

Comment on lines +1451 to +1455
processes: Object.fromEntries(
Object.entries(claim.processes).filter(
([, process]) => process.ownerToken !== input.ownerToken
)
),

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.

P2 Object filter violates standards

The new earlierAttempts.processes block uses Object.fromEntries(Object.entries(...).filter(...)), which the repository's common-utilities rule explicitly forbids. Keep the ownerToken check, but build the filtered record without the banned pattern. Neither filterUndefined nor omit directly replaces this value-based check.

This repository requirement must be satisfied before merging.

Context Used: CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

This branch was previously deployed

1 inactive deployment
Preview — ce76f146 Deployed Oct 15, 2026 by vercel[bot]
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.

2 participants