Files
PaperClipAI/ui
DottaandPaperclip 143d20e466 fix(server): retain native Codex Plan write boundaries (#18034)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native Codex task chat keeps a saved Plan inside the turn that wrote
it.
> - The compact conversation API omits ordinary tool history.
> - That omission also removes the write receipt needed to place the
Plan.
> - This pull request retains a small successful write receipt in
conversation reads.
> - The UI can then keep the saved Plan at its write boundary after
readback.

## Linked Issues or Issue Description

**What happened?**

A real native Codex Product E2E attempt saved its Plan and displayed it
inside a settled turn. The Plan used the fallback position. The
browser's final conversation-only API response contained no
`write_document` receipt. The full event snapshot retained the
successful write. The native placement assertion failed and remains
failed in the original report.

**Expected behavior**

Conversation readback must retain enough evidence to place the saved
Plan at its successful write boundary. It must keep arbitrary tool
bodies and ordinary tool history out of the compact response.

**Steps to reproduce**

1. Save a canonical Plan through a native `write_document` call.
2. Read the run with `view=conversation`.
3. Before this fix, the response omits the write receipt and the UI
places the Plan at the end-of-turn fallback.

Related eval evidence repair: Refs #18026. This is a separate product
readback fix. It does not resolve the failed human-input call or the
Claude tool-availability failure from those attempts.

## What Changed

- Include only successful canonical `plan` document results, matched to
a native `write_document` call in the same run, turn, session and source
instance. Ordinary document writes stay excluded.
- Build the small receipt inside PostgreSQL before its body crosses the
database connection. Preserve only fixed event metadata, tool identity,
the `plan` key and mutation disposition. Keep the existing payload
decoder for ordinary conversation events.
- Keep cursor paging, run scope, ordinary-tool exclusion, and full event
reads unchanged.
- Document the compact read contract in OpenAPI.
- Scope this fix to the canonical native dynamic-tool call/result pair
used by Codex. The retained Claude sample proves compatibility with that
captured shape. It does not qualify every current ACPX Claude producer.
Provider-activity-only paths and OpenCode keep the explicit fallback.

## Verification

- Real PostgreSQL red: the new boundary test fails because the first
selected event is assistant text rather than the saved write. The six
existing tests pass.
- Real PostgreSQL/API green: 36 tests pass across task cold-open and
OpenAPI routes on an isolated Linux current-master checkout.
- UI: 104 transcript tests pass, including completed native placement
from the body-free receipt.
- Review regression red: a later notes write incorrectly enters
conversation readback (one failure, six passes). After the fix, the
PostgreSQL/API suite passes all 36 tests.
- Fixed the new UI fixture's string-to-Date type mismatch found by
hosted CI. Original failed CI remains visible; fresh exact-head checks
are pending.
- Existing token/style gates pass.
- Retained native Codex and Claude fixture shapes both pass. Each
fixture includes the canonical item pair and parallel provider
`tool.execution.*` activity. All identifiers and document bodies in the
fixtures are synthetic. This captured-shape test is historical readback
compatibility, not fresh current-source Claude acceptance. The Codex
canonical pair is emitted by
`packages/paperclip-runner/src/drivers/codex/codex-session-server-requests.ts`
in the admitted dynamic-tool handler.
- Projection-collision regression red: a non-Plan result selected by
conversation identity was relabeled as a Plan. The SQL projection now
uses the same full Plan predicate as selection. The regression and both
native fixtures pass.
- The database test checks cursor paging, a Plan followed by notes,
failed/read/control-plane/unrelated-turn exclusion, schema and ID
bounds, omission of a large tool body, unchanged full-history reads, and
ordinary conversation payloads containing NUL.
- Local server typecheck fails on 80 installed workspace export
mismatches outside changed paths. No changed-path type error or local
full build pass is claimed. Clean hosted checks must pass before merge.
- Current-head hosted CI and legacy status pass. One failed-check retry
followed recorded runner shutdowns and an unrelated native-distribution
timeout; that test passed all 33 cases locally. Original failed logs
remain retained.
- Zero provider calls or paid attempt retries. Original failures and
accounting journals remain unchanged. This is not a new live
qualification result.

## Risks

- Conversation pages include matching Plan results within the existing
1,000-row page limit. The query adds a run-scoped match against
canonical tool calls and projects results inside SQL. PostgreSQL still
reads the stored JSON to select receipts; private bodies are not
transferred to the application. It adds no separate database round trip
or background work.
- Matching requires the existing canonical call/result identities.
Missing or malformed historical receipts keep the explicit fallback.
This fixes compact conversation readback; it does not redesign placement
in an unrelated full-history multi-document UI flow.
- This restores the existing UI write-boundary mechanism. It does not
change Plan acceptance, permissions, or completion rules.

## Model Used

- OpenAI Codex, GPT-6, with reasoning and code execution tools. The
exact serving variant and context window are not exposed in this
session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-28 11:06:05 -05:00
..

@paperclipai/ui

Published static assets for the Paperclip board UI.

What gets published

The npm package contains the production build under dist/. It does not ship the UI source tree or workspace-only dependencies.

Storybook

Storybook config, stories, and fixtures live under ui/storybook/.

pnpm --filter @paperclipai/ui storybook
pnpm --filter @paperclipai/ui build-storybook

Typical use

Install the package, then serve or copy the built files from node_modules/@paperclipai/ui/dist.

Editor dependency identity

Keep the root and workspace overrides for @codemirror/state, @codemirror/view, and @lezer/common aligned. CodeMirror requires shared extension identity, while Lezer parsers and syntax highlighters require shared NodeProp IDs. Multiple Lezer copies can crash code-block highlighting with tags is not iterable. src/lib/codemirror-single-instance.test.ts checks the installed dependency graph and highlights sample code through the editor's real language dependencies. GitHub Actions owns regeneration of pnpm-lock.yaml.