Files
PaperClipAI/maps/feature-map/recovery.md
T
DottaandPaperclip 433d94ee0b refactor(maps): generate indexes from local story and feature metadata (#16214)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Feature recipes and Storybook help contributors find behavior,
examples, and verification steps.
> - Independent feature changes currently update shared catalogs,
indexes, and review hashes.
> - Those shared files cause merge conflicts and repeated bookkeeping
during parallel work.
> - This pull request stores metadata in each feature recipe and story,
then generates the combined views.
> - Contributors can merge independent work without editing a common
index. Git and PR evidence retain change and review history.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Maintaining the product, agent-access, and Storybook maps while multiple
agents change different features.

**Current behavior**

A story or recipe change can update `catalog.json`, `INDEX.md`, review
hashes, verification tables, and tracked generated navigation. Two
unrelated changes then conflict in the same files.

**Proposed behavior**

Each story declares capability links and classification in
`parameters.paperclip`. Each feature recipe declares its navigation and
optional verification guidance. Startup, build, and UI typechecking
discover these sources and generate ignored indexes and Storybook pages.

**Reason and benefit**

A routine change edits its own source files. Aggregate metadata is
rebuilt from the merged checkout. There is no sidecar registry, shared
review journal, or hash acknowledgment to maintain.

**Breaking changes**

The tracked Storybook catalog and index paths are retired. Consumers use
`ui/storybook/generated/` or `maps/generated/` after generation.
Contributor instructions and the existing feature-gap browser suite use
the new paths. Story and overview IDs remain stable.

## What Changed

- Move the existing annotations into 262 story files. Preserve
classifications, capability associations, exports, and explicit IDs.
- Discover all 35 feature recipes. Store section/order beside each
recipe and move durable verification routes out of the shared table.
- Remove tracked catalogs, inventories, overview pages, and inline
preview ordering. Keep authored preview behavior in `preview-base.tsx`.
- Generate the Storybook guide, feature/access Markdown indexes, gap
report, page-reference inventory, and preview wrapper automatically.
- Update the map contracts and maintenance skills to use Git history and
revision-specific PR/CI evidence.
- Add schema, identity, regeneration, and actual Git merge tests. Run
these through the existing UI Vitest suite. Add focused browser
navigation checks.

This is one coordinated migration. Most of the 367 changed files contain
only moved metadata or deleted generated content. Review the generator
scripts, map contracts, Storybook configuration, and tests first. No
product API or authorization behavior changes.

## Verification

Passed:

- `node scripts/check-maps.mjs`: 35 paired areas and 175 capabilities.
- `node scripts/storybook-catalog.mjs --check`: 262 suites and 2,485
authored stories after incorporating current master.
- `node --test scripts/check-maps.test.mjs
scripts/storybook-catalog.test.mjs
scripts/storybook-feature-index.test.mjs`: 28 tests, including
independent branches merged in both orders with identical generated
output and no tracked changes.
- `pnpm --filter @paperclipai/ui exec vitest run
storybook/map-tooling.test.ts`: the CI entrypoint runs those map tests.
- `pnpm check:token-gates`.
- `pnpm -r typecheck` and `pnpm build` before the final master rebase.
- `pnpm build-storybook`: all 2,517 original story/docs URLs retained.
Current master contributes exactly four additional recovery stories.
- Focused Playwright navigation checks: search and open a feature
without examples; expand verification guidance and check source links;
retain capability order and follow a related Foundations suite.

The final clean Storybook build passed after deleting every ignored map
output. Post-rebase UI typechecking and both browser tests passed. The
working tree stays clean after generation. The concurrent-cleanup
regression fails with `ENOENT` without the fix and passes with it.

All GitHub CI gates passed on `00fc7ec18e`, which also received Greptile
5/5 with no unresolved findings. The final merge commit `1c3c5143a6`
incorporates master and resolves only the two modify/delete conflicts by
retaining removal of the aggregate index and catalog. Master’s new
workspace feature and access guidance is preserved. Map validation,
catalog generation, overview generation, all 28 map tests, and diff
checks pass after conflict resolution. The maintainer explicitly
requested merging without another Greptile review. CI has not been rerun
to completion on this merge commit. The local repository-wide `pnpm
test:run` was stopped before completion after the earlier CI matrix
passed; it is not reported as a local pass. No screenshot baselines or
production acceptance are claimed.

To repeat the browser check against an owned Storybook server:

```sh
PAPERCLIP_GAP_STORYBOOK_URL=http://127.0.0.1:6136 pnpm exec playwright test --config tests/storybook-visual/feature-gap-stories.config.ts map-navigation.spec.ts
```

## Risks

- Existing branches need a one-time rebase to move their catalog changes
into local annotations. The PR incorporates the recovery changes from
current master.
- Changing the same story or capability can still produce a meaningful
conflict. This removes the shared aggregate bottleneck.
- The generator uses Storybook's existing CSF parser. Literal-only
annotations and parser regression tests protect the current contract.
- Generated Markdown is available after running the generator; the
published Storybook provides a browsable guide.
- Shared source changes still require review. Removing hashes removes
mechanical acknowledgments; it does not establish runtime parity.

## Model Used

OpenAI Codex, based on GPT-6, with repository inspection, code
execution, and browser-test tools. The exact deployment model ID and
context window were 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 on the previously reviewed head
`00fc7ec18e`; final conflict-resolution checks are documented above
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
on `00fc7ec18e`; another review was waived by the maintainer
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 15:27:23 -05:00

15 KiB

navigation
navigation
section sectionOrder order
Projects and execution 40 50

Recovery

People can see why a task stopped, who owns the next action, and whether a safe continuation is available. Recovery retains task context and ownership, honors pause and budget gates, and distinguishes confirmed failure from an uncertain external outcome. A retry acknowledgement alone is not proof that work resumed.

Agent access: companion.

Sub-features

  • diagnosis: a task/run exposes the recorded cause, evidence, owner, attempt progress, and next action without requiring a raw-log interpretation.
  • bounded-continuation: supported interrupted work continues with preserved conversation context and bounded attempts, without blindly replaying tools.
  • source-action: source-scoped recovery actions remain attached to the task; independent repair work may have its own issue and return owner.
  • exhaustion: exhausted or overdue recovery exposes the current gate and permitted operator action; it does not claim an automatic path is still live.
  • workspace: workspace divergence/export failures show the applicable repair, reconcile, or isolated reissue action with evidence and authority checks.
  • unknown-outcome: uncertain external side effects require inspection and an explicit decision, not automatic replay.
  • user-continuation: saved user messages after a stop are reconsidered once cleanup proves the old execution is stopped; duplicate wakes are avoided.
  • reconnect: browser stream recovery refreshes persisted state without claiming the agent itself restarted or that a failed run succeeded.

How to get to it (user POV)

source-task

Open the affected task from Tasks, Inbox/Blocked, search, or a direct task link. Inspect the recovery notice/card in its history, expand details if needed, and use the currently offered action. Follow any linked repair task and return owner.

run-detail

Open the agent's run (/agents/:agentId/runs/:runId) from activity or the task's run link. The run page hosts workspace recovery controls only for a failed run with error code workspace_validation_failed and a linked source task that still has a live workspace_validation recovery action. Use the source task for other stopped-run recovery checks.

operator-retry

On an exhausted disposition or workspace recovery card, inspect the current reason and use the permitted retry/repair/reconcile action. Some repairs require confirmation; unavailable actions must explain the gate or remain absent.

post-stop-message

After a stop, send a new instruction on the same task or inspect one already saved while cleanup was pending. Observe the waiting message, continuation, and eventual result rather than manually changing the task status to look complete.

browser-reconnect

While viewing an active or recovering task, interrupt the browser connection and restore it, or suspend and return to the tab. Reload is a separate check. The current task and run state should reconcile with the server.

Driving it

Preconditions: follow the baseline. Use a disposable instance and reproducible failure. Record source task/run, adapter/runtime mode, cause, attempt count, current owner, and verified stop evidence. Do not kill an unrelated server or induce provider side effects just to get a failure screen. Use the existing deterministic recovery suite first.

source-task

Automated: recovery actions covers source scoping, bounded attempts, operator stops, quota monitoring, ownership, stale action retirement, and continuation deduplication. Recovery cards cover diagnosis, retry progress, exhaustion, and action availability. The fixture-backed execution-recovery journeys start their own test-drive instances and exercise safe, uncertain, restart, manager-lineage, and legacy-unknown paths:

pnpm exec vitest run server/src/__tests__/issue-recovery-actions.test.ts ui/src/components/IssueRecoveryActionCard.test.tsx
pnpm exec playwright test -c tests/e2e/execution-recovery/playwright.config.ts recovery.spec.ts

Manual: open a stopped task through each affected navigation path. Confirm its explanation, original owner, recovery owner if different, and next action. Follow the supported recovery until the source task produces a useful result or a specific escalation. Reload and verify that resolved notices retire and attempt history remains. A fixture pass does not qualify every live harness/provider.

For a native workspace owner hold, repeat issue reads and recovery checks after the task becomes done or cancelled. Verify one unchanged action ID, attempt count, and timestamps; task completion must not authorize copyback. Clear only the exact receipt after operator stop verification, then confirm stale action cleanup. The route regressions and heartbeat regression cover this sequence without a live operator recovery claim.

run-detail

Automated: run workspace recovery tests this host; it is component coverage, not an end-to-end repair.

Manual: prepare a failed run with error code workspace_validation_failed, a linked source task, and a live workspace_validation recovery action on that task. Open that exact run and compare its recovery diagnosis to the source task. Use an eligible action from the run surface, return to the task, and verify the same action state, persisted outcome, and restored execution. Repeat with an actor who lacks authority. Verify that the run-page controls are absent for other error codes or after the source action retires; continue other recovery checks on the source task. Full run-detail navigation remains a manual gap.

operator-retry

Automated: disposition notices tests pending/error/gated states and waiting for the real retry acknowledgement. The recovery-card suite covers workspace divergence, reissue, reconcile, and confirmation. Workspace export covers quiet restoration, legacy/operator assistance and resolved states.

For a retained legacy file hold, open the source task after its recovery action has resolved but its files still need recovery. An authorized board operator can record the verified recovered files and backup link without changing the current task status or starting another run. The server must independently validate the original stopped-execution receipt. Agent Chat must show the file hold rather than suggesting another message. The file recovery form, notice, and repair route cover evidence/confirmation, read-only access, stale or missing stop proof, source-only repair, and preserved task status. These tests use fixtures; separately verify original files and their attached artifact before recording a real repair.

For an abandoned native copyback owner, the harness verifies the exact stopped deployment and the reconciler restores saved work automatically. Task users see no process details or shutdown form. The documented operator API handles older receipts after independent platform verification, through a separate administrator gate. The authorization regressions and route regressions cover administrator admission, ordinary-member and agent denial, suspended and foreign membership, missing role data, and stale cloud admin rows. The native workspace finalizer suite runs the real reconciler with a valid saved yield from result_accepted, workspace_finalizing, and retryable_failure. It verifies physical fencing before verified stop, automatic and operator recovery, successful export and commitment, hold resolution, unchanged saved results, retained approval/monitor waits, and no new provider wake. These local regressions do not prove a deployment platform stopped a foreign writer.

Manual: reproduce an exhausted disposable action. Click once, verify pending state prevents repeated clicks, and inspect a successful continuation or an explicit rejection. Reload to confirm the durable outcome. For a workspace repair, record the compared branches/revisions and preserve uncommitted work; confirm the repair's actual result before resuming. Check the denied and stale action paths. A changed card label is insufficient proof of workspace integrity.

For an abandoned native controller, follow the stop-verification procedure with a disposable deployment. A new platform-bound owner recovers automatically only after the harness signs proof that the exact deployment fully stopped. Legacy owners require independently verified stop evidence through the operator API; the task has no shutdown form. Confirm the original accepted result commits, the recovery hold resolves, saved files remain intact, and existing approval waits or monitor checks remain. No new agent turn should start. Repeat with a retry-phase owner and an ordinary runtime manager; the first can resume through automatic proof or authorized operator confirmation, while the second cannot use the operator API.

post-stop-message

Automated: legacy continuation, queue routes, and native restart recovery cover their respective recovery paths. Legacy failure continuation adds a browser journey; it is not native runtime proof.

Manual: stop a disposable run, submit a distinguishable follow-up, and observe any cleanup wait. After confirmed stop, verify the follow-up reaches one eligible continuation and produces the requested answer. Repeat with a task/ancestor pause and a budget hold: recovery must not bypass the gate. For unknown external outcomes, inspect the provider before authorizing another operation.

browser-reconnect

Automated: live-update recovery covers client transport recovery with mocks. It does not prove runner restart.

Manual: go offline during a disposable run, let the server reach a new state, then reconnect. Confirm task/run/attention data refresh without duplicate comments or decisions; reload and compare. A healthy websocket proves transport only. Separately inspect the underlying execution if it is still stuck.

Gotchas

  • Legacy and native runtimes have different ownership and restart paths. Record which one was exercised instead of inferring coverage from the adapter name.
  • A process disappearance, elapsed timeout, or successful API retry does not prove an external tool operation never happened. Unknown outcomes stay unknown until corroborated; automatic replay can duplicate a side effect.
  • Active-run watchdogs, task watchdogs, reviewers, and recovery owners have different authority. No recovery card grants board permission by itself.
  • Idle Agent Chat is not stranded work. An intentional operator stop must not silently trigger recovery that fights the user's instruction.
  • Source inspection and mocked component tests do not qualify real server restart continuity. Use the appropriate runtime suite for that claim.
  • See execution semantics for the governing recovery contract and steering for saved follow-ups.

Storybook verification

exhaustion

Scope: ui Storybook: Exhausted/overdue attempts, operator retry pending/error, blocked authority/gate and specific escalation. Production: Inspect durable attempt bounds and actual eligible retry/repair; acknowledgment alone does not prove continued execution. Sources: Source: IssueRecoveryActionCard.tsx, DispositionRecoveryNotice.tsx, issue-recovery-actions.ts. Tests: IssueRecoveryActionCard.test.tsx, DispositionRecoveryNotice.test.tsx, issue-recovery-actions.test.ts, recovery.spec.ts

unknown-outcome

Scope: ui Storybook: Uncertain external outcome, required inspection/evidence and explicit permitted operator decision. Production: Corroborate provider outcome before authorization; enforce no automatic external side-effect replay and reject stale/unauthorized decisions. Sources: Source: IssueRecoveryActionCard.tsx, issue-recovery-actions.ts. Tests: IssueRecoveryActionCard.test.tsx, issue-recovery-actions.test.ts, recovery.spec.ts

user-continuation

Scope: ui Storybook: Saved follow-up waiting on stop cleanup, pause/budget gate, one eligible continuation and result/failure. Production: Confirm previous execution stopped before delivery, preserve message, avoid duplicate wakes and honor actual task/ancestor/budget gate in separate legacy/native paths. Sources: Source: TaskChatQueuedMessages.tsx, legacy-continuation.ts, native-restart-recovery.ts. Tests: legacy-continuation.test.ts, native-restart-recovery.test.ts, issue-queued-comments-routes.test.ts, legacy-failure-continuation.spec.ts