Commit Graph
8 Commits
Author SHA1 Message Date
0a09e4d975 feat(decisions): add desk workflow and retention (#10672)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Decisions desk shows work that needs a human decision
> - The queue foundation can group and rank decision work
> - Operators also need a focused daily view and a safe way to handle
old work
> - This pull request adds the desk controls, the aging shelf, and
reversible retention
> - It also binds bulk archive decisions to the exact reviewed item set
> - The benefit is a smaller daily queue without lost or orphaned work

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting: server, UI, database, and shared contracts.

**Problem or motivation**

Decision work can grow into one large company list. Operators need quick
queue and date controls. Old items also need a safe retention path that
does not delete work.

**Proposed solution**

Add queue and date controls to the Decisions desk. Compute the aging
shelf on the server. Archive idle items after 90 days unless an operator
keeps them. Keep archived items searchable and revivable. Notify origin
agents in one batch per sweep. Bind bulk archive proposals to a signed,
exact item manifest.

**Alternatives considered**

Client-only aging can drift across browsers and source kinds. Deleting
old rows removes audit and recovery paths. An unsigned dynamic bulk
query can archive items that the reviewer did not inspect.

**Roadmap alignment**

This work supports the Work Queues and decision-memory directions in
`ROADMAP.md`. It extends the Decisions and attention-feed foundation
from #10651. Related earlier work includes #9380, #10010, and #10474.

## What Changed

- Added the queue rail, date chips, decide split, triage strip, queue
page, and aging shelf UI.
- Added server-owned shelf state with per-queue retention overrides.
- Added reversible retention state, archive history, and an idempotent
notification outbox.
- Added the 90-day archive sweeper, Keep exemption, archived feed query,
and revive actions.
- Added one origin-agent notification per agent and sweep.
- Added signed bulk archive proposals with exact-set and version checks.
- Persisted queue-exclusion reasons atomically and kept cross-domain
source resolution per-item until it has an exact-set transaction
contract.
- Added API contracts, OpenAPI entries, migration coverage, focused
tests, and Storybook screens.

## Verification

- `pnpm -r typecheck`
- `pnpm test:run` (server: 329 files and 3,453 tests passed; UI: 408
files and 3,362 tests passed)
- `env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY pnpm exec vitest
run cli/src/__tests__/secrets.test.ts`
- `pnpm build`
- `pnpm check:token-gates`
- Focused retention, attention, decisions, migration replay, startup,
and UI API tests.
- Complete queue snapshot regression with 51 items across the normal
50-item page boundary.

The unmodified CLI test reports one warning assertion in this runtime
because the harness injects static AWS credential variables. The
isolated test passes when those two variables are removed.

## Risks

- The migration adds retention and notification outbox tables. It uses
idempotent table, index, and foreign-key creation.
- Retention runs on the heartbeat scheduler interval. Compare-and-set
version checks prevent stale archive writes.
- Bulk archive acceptance fails closed when authority, activity,
version, or the reviewed set changes.
- Archive is reversible and does not delete source records.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex with `gpt-5.6-sol`. The model used tool calls, code
execution, database migration generation, and test execution. The
context-window size is not exposed in this runtime.

## 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: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-02 10:47:03 -05:00
9c1f8e7887 feat(decisions): add first-class propose mode (#10010)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents can currently perform many mutations directly, while humans
often need a durable review point before cross-issue or destructive
actions occur
> - Existing approvals and issue-thread interactions do not provide a
standalone, reusable object for presenting options, collecting typed
inputs, detecting stale targets, and auditing effect execution
> - The control plane therefore needs a first-class propose mode that
separates an agent's recommendation from the governed mutation it may
cause
> - This pull request adds Decisions v1 across the database, shared
contracts, server execution and telemetry, agent skill guidance, and
operator UI
> - The benefit is that agents can propose multi-option actions safely
while operators get explicit provenance, fail-closed execution,
per-effect results, and a focused attention workflow

## Linked Issues or Issue Description

### Subsystem affected

Cross-cutting: `packages/db`, `packages/shared`, `server`, and `ui`.

### Problem or motivation

Agents need a governed way to propose consequential work without
immediately mutating issues, especially when one choice can affect
several issue trees. Existing approvals and issue-thread interactions do
not provide a standalone object with typed options, target snapshots,
effect-level authorization, expiration, execution outcomes, and reusable
attention-feed presentation.

### Proposed solution

Add first-class Decisions that store options and typed inputs, surface
open proposals in the operator attention feed, validate target freshness
and the origin-agent/operator authorization intersection at decision
time, execute a bounded set of auditable effects, and retain terminal
outcomes. Decisions v1 supports comments, status and assignee changes,
follow-up issue creation, blocker resolution, and issue-tree
cancellation, plus bundle grouping, expiration/dismissal, rule-key
telemetry, and agent-facing API guidance.

### Alternatives considered

- Extend approvals with arbitrary effects: rejected because approvals
represent governed yes/no actions and would become an unsafe generic
mutation envelope.
- Model every proposal as an issue-thread interaction: rejected because
decisions can span several targets and need independent lifecycle,
telemetry, idempotency, and effect results.
- Let agents perform the mutation and ask for retrospective review:
rejected because it removes the pre-execution governance boundary this
feature is meant to provide.

### Roadmap alignment

Aligns with `ROADMAP.md` sections **Agent Reviews and Approvals**,
**Enforced Outcomes**, **MCP Tool Gateway & Apps (governed tool
access)**, and **Activity History** by making explicit decisions,
authorization gates, auditable execution, and terminal outcomes
first-class control-plane objects.

### Additional context

This does not replace existing approvals or issue-thread interactions,
and it does not add an unrestricted generic mutation effect.

## What Changed

- Added company-scoped decision, option, target, and effect-execution
schema plus migration and shared TypeScript/Zod contracts.
- Added decision routes and services for propose, list/get, decide,
dismiss, cancel, target freshness checks, authorization intersection,
idempotency, activity logging, and execution auditing.
- Added rule-key decision telemetry and attention-feed metadata so open
decisions are visible and measurable.
- Added agent skill documentation for proposing and resolving decisions
through the Paperclip API.
- Added the Decisions UI: API client, query keys, inline attention
resolver, bundle grouping, target-issue strip, terminal history,
destructive confirmation, and per-effect result rendering.
- Added server service coverage, DecisionCard state tests, and Storybook
stories for the supported visual states.

## Verification

- `pnpm -r typecheck` — passed.
- `pnpm test:run` — 2,876 passed, 1 skipped, with one unrelated
cross-suite cleanup-order failure in
`heartbeat-responsible-user-invariant.test.ts`; the failing file passes
in isolation (`6/6`).
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-responsible-user-invariant.test.ts` — passed.
- `pnpm --filter @paperclipai/ui exec vitest run
src/components/DecisionCard.test.tsx` — passed (`9/9`).
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/authz-existence-oracle-guard.test.ts
src/__tests__/openapi-routes.test.ts` — passed (`5/5`).
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/decisions-service.test.ts` — passed (`16/16`).
- `pnpm --filter paperclipai exec vitest run
src/__tests__/company-import-export-e2e.test.ts` — passed (`1/1`).
- `pnpm --filter @paperclipai/server typecheck` and `pnpm --filter
paperclipai typecheck` — passed.
- `pnpm build` — passed.
- Rebased-head focused suite — passed (`6` files, `88` tests): shared
decision contracts, Decisions service, OpenAPI routes, startup feedback
export, DecisionCard states, and attention helpers. The follow-up
stale-secondary-target regression passes in the DecisionCard suite
(`10/10`).
- Rebased-head scoped typechecks — passed for `@paperclipai/shared`,
`@paperclipai/db`, `@paperclipai/server`, and `@paperclipai/ui`.
- Rebased-head migration numbering and safety checks — passed after
renumbering the additive migration to `0193` and making it replay-safe
for environments that applied the earlier feature-branch number.
- `pnpm check:token-gates` — passed with all gates clean.
- GitHub PR workflow and Greptile review for
`1f9f7645882d05dfdd9c99377c03a1f53f20e8be` — running after the
stale-secondary-target fix and PR metadata refresh on July 27, 2026.
- `pnpm --filter @paperclipai/ui build-storybook` exposes an existing
Storybook version mismatch (`storybook` 10.4.6 vs
`@storybook/addon-docs` 10.5.0); Decisions stories were validated with
the docs addon temporarily disabled and the tracked config remains
unchanged.

## Risks

- **Migration:** Adds replay-safe migration `0193`; migration numbering
and safety checks pass. The new tables and indexes are additive.
- **Authorization:** Effect execution intersects the proposing agent's
permissions with the responsible user context and fails closed; mistakes
could reject a valid proposal rather than silently over-authorize it.
- **Concurrency:** Target snapshots and idempotency keys protect against
stale or duplicate execution, but reviewers should focus on mixed-effect
partial outcomes and retry behavior.
- **UI:** Decisions are integrated into the existing attention feed
rather than a separate navigation surface, reducing routing risk but
increasing the importance of attention-item metadata compatibility.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex CLI using `gpt-5.6-sol` for final PR preparation, review
fixes, and verification; repository tools and code execution were
enabled, and context-window size is not exposed in this runtime.
- Anthropic Claude Opus 4.8 with 1M context assisted with the Decisions
UI implementation, as recorded in the relevant commits.

## 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>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-31 19:17:02 -07:00
TonioandClaude Opus 5 492555aaf9 design(decisions): flatten decision cards to two task-borrowed types (#10474)
The Decisions queue ran five parallel colour/icon vocabularies chosen by
source kind, plus a separate severity badge, so two rows needing the same
response could look unrelated and none of it matched the task list.

Every row now resolves to one of two kinds, each borrowing the task status
it corresponds to: blocking renders as `blocked`, review as `in_review`,
both through StatusGlyph and the existing --status-task-icon-* tokens.
Source kinds keep their own wording; only colour and icon merge.

Card anatomy follows the design mock: no left accent rail, rounded cards
16px apart, a "/"-separated meta breadcrumb, a named See more / See less
control, and no separately tinted drawer when expanded. Verb order is
fixed across both states. Severity moves from chrome to a toolbar filter.

Four defects fixed along the way:
- blocked rows reported themselves as their own blocker (server-side)
- the task key was missing wherever the row's subject IS the task
- the task quicklook stuck open, because closing handed focus back to a
  trigger that opens on focus
- the card ring appeared on click, and only on cards with a toggle

Also: the standard task preview is aligned to its trigger's text and
scales out of it, the task eyebrow renders its project as a tile, and the
first motion tokens land alongside the disclosure and crossfade.

Supersedes #9574 and #9575.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 18:43:40 -07:00
DottaandPaperclip 051ae4d102 feat: restore decision training library and inspector (#9779)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies and supervise governed work.
> - Decisions capture high-value operator judgment, and the
decision-training foundation merged in #9702 freezes that evidence for
later evaluation and learning.
> - Operators still need the UI from the closed stacked PR #9718 to
intentionally capture examples and inspect the resulting dataset.
> - GitHub automatically closed #9718 when its stacked base branch was
deleted after #9702 merged, leaving the server foundation on `master`
without the corresponding UI.
> - This pull request restores the final UI and its still-required
supporting API fields directly on current `master`, while excluding the
obsolete migration and duplicated server-foundation diffs.
> - The benefit is a reviewable replacement PR that preserves the
completed decision-training workflow without replaying stale stack
history.

## Linked Issues or Issue Description

- Refs #9718
- Refs #9702

## What Changed

- Restored the top-level `/training` library and record inspector with
search, filters, JSONL export, notes editing, and evidence tabs.
- Restored the Decisions-row training affordance and capture drawer,
including preview, provenance, deletion, cache refresh, and approval
consistency behavior.
- Restored the shared types and focused server support needed by the UI
without reintroducing decision-training migrations or the already-merged
server foundation.
- Restored focused UI and attention-service tests from the final #9718
state.
- Credit to the authors and reviewers of #9718; this recovery
transplants their final reviewed delta after the stacked base deletion.

## Verification

- `pnpm exec vitest run ui/src/pages/Training.test.tsx
ui/src/components/DecisionTrainingDrawer.test.tsx
ui/src/components/AttentionQueueRow.test.tsx
server/src/__tests__/attention-service.test.ts
server/src/__tests__/decision-training.test.ts` — 5 files, 48 tests
passed.
- `pnpm --filter @paperclipai/shared typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts` — 3
tests passed; confirms exact route/OpenAPI parity for the restored
preview endpoint.
- `pnpm check:token-gates` — the restored files are clean; the
repository-wide command currently reports five pre-existing false
positives where comments reference GitHub issue `#9627` as if it were a
color literal.

## Risks

- Low migration risk: this PR contains no database migrations and is
based directly on current `master`.
- The main behavioral risk is cache invalidation across Decisions and
Training views; focused tests cover capture, update, deletion, row
state, and approval refresh behavior.
- The token-gate baseline remains red on unrelated `#9627` comment
references; this PR does not modify those files.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5.3-Codex, reasoning with repository/tool access and
code execution. Context window not exposed by the runtime.

## 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-07-17 13:27:32 -05:00
DottaandPaperclip f1508a7929 feat(decisions): expand image rows into gallery (#9532)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies and review work that needs human attention.
> - The Decisions page condenses approvals, failed runs, reviews, and
issue interactions into a scannable attention queue.
> - Some decision rows already include screenshot evidence, but the
collapsed thumbnail stack is too small for meaningful inspection.
> - Image-only rows were not expandable because expansion was previously
reserved for inline decision resolvers.
> - Reviewers therefore had to leave the Decisions page before they
could understand the visual evidence attached to a row.
> - This pull request makes rows with images expandable and presents a
readable, linked gallery while preserving the compact collapsed view.
> - The benefit is faster evidence review without sacrificing queue
density or existing inline-resolution behavior.

## Linked Issues or Issue Description

No public GitHub issue currently tracks this feature.

### Subsystem affected

`ui/` — React + Vite board UI

### Problem or motivation

Screenshot evidence in Decisions rows is only visible as small
overlapping thumbnails, and non-inline rows cannot expand to show it.
This makes visual review unnecessarily slow and forces reviewers to
navigate away from the queue.

### Proposed solution

Treat active rows with images as expandable, render the first three
images at a readable size in an expanded gallery, and link images plus
any remaining-image affordance to the related issue.

### Alternatives considered

Always rendering large images would make the queue difficult to scan;
opening the issue immediately preserves density but prevents in-context
review. An explicit expandable gallery keeps both behaviors available.

### Roadmap alignment

`ROADMAP.md` does not list overlapping Decisions image-gallery work.
This is a focused improvement to the existing review surface rather than
a new product area.

### Additional context

The Storybook variants document both the collapsed thumbnail treatment
and deterministic expanded gallery state for reviewer inspection.

## What Changed

- Allow active Decisions rows with screenshot evidence to expand even
when they have no inline resolver.
- Keep compact thumbnails in collapsed rows and render up to three
larger, linked images when expanded.
- Add an accessible remaining-image tile that links to the related issue
when more screenshots exist.
- Add component coverage for image-only expansion and the
remaining-image issue link.
- Add collapsed and expanded image-gallery Storybook variants, including
deterministic initial expansion.

## Verification

- `pnpm exec vitest run ui/src/components/AttentionQueueRow.test.tsx`
- `pnpm check:token-gates`
- `pnpm --dir ui typecheck`
- `pnpm --dir ui build-storybook`
- QA visual verification (light + dark, no defects):
https://github.com/paperclipai/paperclip/pull/9532#issuecomment-4964769485

## Risks

- Low risk: the change is isolated to Decisions row rendering and
Storybook fixtures.
- Rows with images gain a new expansion interaction, but existing inline
resolver behavior and deep links remain intact.
- The gallery intentionally limits the in-row preview to three images to
avoid unbounded row height.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Opus 4.8 assisted with the original implementation
and tests.
- OpenAI `gpt-5.4` via Codex CLI assisted with current-master rebase
integration, verification, and PR preparation. The runtime
context-window size is not exposed; capabilities used include reasoning,
repository tool use, code execution, and test execution.

## 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-07-15 20:08:21 -05:00
DottaandPaperclip c36f1a4afd fix(ui): make mobile decision rows readable (#9472)
## Thinking Path

> - Paperclip is the open source control plane people use to coordinate
AI-agent companies
> - Human operators use the Decisions attention queue to review and
resolve work that needs them
> - Decision rows were composed as a fixed content column plus a
right-side controls column
> - At phone widths, timestamps, actions, menus, and evidence thumbnails
compressed the decision headline until it was barely readable
> - This pull request makes each row respond to its own container width
and stacks metadata, content, evidence, and actions on narrow surfaces
while preserving the dense desktop layout
> - The benefit is a useful, thumb-reachable Decisions workflow on
phones and narrow side panels without regressing wide-screen density or
scrolling performance

## Linked Issues or Issue Description

No public GitHub issue exactly matches this bug, so it is described here
using the bug-report fields.

**What happened**

Decision rows used a fixed two-column layout. On narrow screens, the
right-hand timestamp, overflow menu, decision buttons, and optional
thumbnails squeezed the headline into a truncated sliver.

**Expected behavior**

Decision headlines should remain readable on mobile, supporting context
should flow below the headline, and primary actions should remain easy
to tap. Wide rows should retain the compact desktop presentation.

**Steps to reproduce**

1. Open the Decisions / What needs me surface with populated attention
items.
2. Reduce the row container to a phone-width layout (approximately
390px).
3. Observe rows with multiple actions or evidence thumbnails.

**Paperclip version / deployment mode**

Current `master`, board UI in local or hosted deployments.

**Related public work found during dedup search**

- Refs: #9311 — original What needs me attention queue work.
- Refs: #9468 — recent Decisions scrolling performance work preserved by
this change.

## What Changed

- Reworked `AttentionQueueRow` into a container-query-driven vertical
stack on narrow surfaces, with the existing compact layout restored at
wide row widths.
- Made decision titles wrap to two lines, moved project/evidence context
below the headline, and promoted actions to full-width mobile tap
targets.
- Preserved upstream row memoization and `content-visibility` scrolling
optimizations while rebasing onto current `master`.
- Added three 390px Storybook scenarios covering populated rows,
type/detail variants, and snoozed/dismissed curtains.
- Updated the focused row test to assert the new thumbnail/context
alignment.

## Verification

- `pnpm exec vitest run ui/src/components/AttentionQueueRow.test.tsx` —
1 file passed, 16 tests passed.
- `pnpm check:token-gates` — all token gates clean.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/ui build-storybook` — completed
successfully.
- `git diff --check public/master...HEAD` — passed.

## Risks

- Low risk: the behavior is isolated to the Decisions row presentation
and its Storybook coverage.
- Container-query breakpoints could need future visual tuning for
unusual embedded widths, but the wide layout remains available at the
row-level breakpoint.
- The mobile layout increases row height by design in exchange for
readable content and usable actions.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex CLI coding agent. The exact model ID and context-window
size are not exposed to this runtime; reasoning, repository editing,
shell execution, and test execution capabilities were enabled.

## 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-07-12 21:28:38 -05:00
8a0db228a6 perf(ui): improve Decisions scrolling performance (#9468)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators use the Decisions page to review an uncapped attention
feed across active, snoozed, and dismissed items
> - Large feeds mounted every row eagerly, and routine interactions
re-rendered the full queue
> - That made initial paint and scrolling progressively slower as
decision history accumulated
> - This pull request bounds rendering, stabilizes row props, and lets
off-screen rows skip layout and paint work
> - The benefit is a responsive Decisions page even for companies with
large attention histories

## Linked Issues or Issue Description

### What happened?

Opening `/decisions` for a company with a large attention history
eagerly mounted every visible-feed row. Expanding, selecting,
dismissing, snoozing, or restoring an item could also re-render the
entire queue.

### Expected behavior

The page should render a bounded initial window, progressively reveal
more rows near the scroll boundary, and avoid re-rendering unaffected
rows during interactions.

### Steps to reproduce

1. Populate a company with hundreds of attention items.
2. Open `/decisions`.
3. Scroll and interact with individual rows.
4. Observe increasing initial render, layout, paint, and interaction
cost on the previous implementation.

### Paperclip version or commit

Reproduced on `master` before this PR.

### Deployment and installation

Local development, built from source. This is a core UI issue, not
adapter- or database-specific.

### Additional context

Searched open public issues and PRs; no duplicate was found.

## What Changed

- Added a pure `planAttentionRenderRows` helper that allocates one
render budget across active groups and open snoozed/dismissed curtains
in document order.
- Render 50 rows initially and add 100 more when the Decisions page
approaches the scroll boundary.
- Memoized `AttentionQueueRow`, stabilized parent callbacks and inbox
dismissal actions, and passed row items through a shared expand
callback.
- Added `content-visibility: auto` and intrinsic containment so
accumulated off-screen rows avoid unnecessary layout and paint work.
- Added render-plan coverage and a regression test proving identical row
props do not re-render after a parent update.

## Verification

- `pnpm -C ui typecheck`
- `pnpm -C ui exec vitest run src/lib/attention.test.ts
src/components/AttentionQueueRow.test.tsx
src/components/Sidebar.test.tsx src/pages/Inbox.test.tsx` — 96 tests
passed
- `pnpm check:token-gates` — all gates clean

## Risks

- Low risk: the change is UI-only and does not alter API or database
contracts.
- The main behavioral risk is incorrect row-budget accounting across
collapsed groups or open curtains; the pure planner has focused tests
for ordering, truncation, and collapsed/closed sections.
- Progressive rendering means rows beyond the current budget are
intentionally absent until scrolling nears the boundary, matching the
existing Issues list pattern.

> This is a targeted performance fix and does not overlap planned core
feature work in `ROADMAP.md`.

## Model Used

- Anthropic Claude Fable 5 assisted with the implementation using
repository tools and code execution.
- OpenAI Codex `gpt-5.6-sol` prepared and verified the PR with high
reasoning effort, repository tools, shell execution, and
GitHub/Paperclip API access. The runtime did not expose a context-window
size.

## 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 (no
documentation changes were required for this UI-only behavior)
- [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: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-12 20:44:52 -05:00
36ec79c196 feat: add attention queue and Decisions surface (#9380)
## Thinking Path

> - Paperclip is the control plane for autonomous AI companies, where
operators need a reliable way to find and act on work awaiting their
input.
> - The attention and issue-thread interaction subsystems expose those
decision points across server APIs and the board UI.
> - The previous navigation and interaction presentation left these
actions fragmented and did not offer a controlled rollout for the
Decisions surface.
> - This branch adds the attention feed, richer interaction cards,
grouping, dismiss/snooze behavior, and a gated Decisions sidebar entry.
> - It also keeps experimental settings and API contracts synchronized,
with an idempotent migration for the new dismissal state.
> - This pull request delivers the complete, tested attention/Decisions
experience as one reviewable unit.

## Linked Issues or Issue Description

- Adds an operator-focused attention queue and Decisions experience:
grouped decision cards, semantic interaction actions, dismiss/snooze
handling, resilient interaction states, and an experimental flag to
control the Decisions navigation entry.


## Feature Context

### Problem or Motivation

Operators currently have to hunt across approvals, interactions, failed
runs, and budget alerts to find decisions that need their action.

### Proposed Solution

Provide a gated Decisions attention queue that groups actionable items,
supports direct resolution, and preserves operator control through
dismiss and snooze actions.

### Alternatives Considered

Keep separate, source-specific views only; this leaves cross-cutting
operator decisions fragmented and harder to prioritize.

### Roadmap Alignment

This improves the V1 control-plane operator workflow by making pending
governed actions discoverable in one company-scoped surface.

## What Changed

- Added server attention-feed services, routes, interaction handling,
dismiss/snooze support, and an idempotent `0145` inbox-dismissal
migration.
- Added shared attention, inbox-dismissal, and experimental-settings
contracts.
- Added Decisions/attention UI, interaction-card states, sidebar
badge/navigation integration, grouping, keyboard support, and Storybook
coverage.
- Added tests for attention behavior, thread interactions, settings
normalization, dismissals, and API behavior.
- Removed generated screenshots from the final PR diff and rebased the
branch onto current `master`.

## Verification

- `pnpm check:token-gates` — passed.
- `pnpm exec vitest run
packages/shared/src/issue-thread-interactions.test.ts
server/src/__tests__/attention-service.test.ts
server/src/__tests__/inbox-dismissals.test.ts
server/src/__tests__/issue-thread-interactions-service.test.ts
server/src/__tests__/issue-thread-interaction-routes.test.ts
ui/src/lib/attention.test.ts
ui/src/components/AttentionQueueRow.test.tsx
ui/src/components/IssueThreadInteractionCard.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx` — passed: 158 tests
across 9 focused files.
- GitHub Actions for `ad636f560`: build and typecheck/release-registry
have passed; remaining general-server and Greptile checks are in
progress.

## Risks

- Moderate: this is a cross-layer attention/interaction feature with a
new migration and navigation behavior.
- The `enableDecisions` experimental setting defaults to off, limiting
rollout impact.
- Existing dismissal data is backfilled to `dismiss`; the migration is
idempotent and uses guarded constraint creation.

> ROADMAP.md was checked; no duplicate planned core feature was
identified. Related open pull requests were searched before opening this
PR.

## Model Used

- OpenAI GPT-5.5 via Codex CLI, with tool use and local code execution.
Context-window size unavailable in this environment.

## 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 public PR branch name describes the change and contains no
internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally; focused tests pass and the remaining
unrelated AWS test failure is documented above
- [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
- [ ] All Paperclip CI gates are green
- [ ] 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>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 17:09:57 -05:00