mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-04 11:01:16 +01:00
docs: keep the feature map focused on substantial features (#18767)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The feature map describes product capabilities and user journeys. > - Small fixes and test changes have added long notes to that map. > - These notes make substantial features harder to find. > - This pull request removes those additions from the last week's changes and sets a clear rule for future additions. > - The benefit is a smaller map with stable capability IDs and accurate entry points. ## Linked Issues or Issue Description **Issue type** Unclear or confusing documentation. **Where is the issue?** `maps/feature-map/`, the map maintenance instructions, and repository rules. **What's wrong?** Between October 27 and November 3, 2026, 115 commits changed the feature map. Many additions describe bug fixes, performance details, small UI changes, or new tests. They do not introduce substantial product features. The old synchronization instructions also encouraged a map edit for every behavior change. **Suggested fix** Add a rule that requires a substantial new feature before expanding the map. Remove minor-update notes. Keep genuine feature additions and minimal corrections to existing instructions. The review covers master through `b22ef22d56`; it does not revert application code. Conflict resolution preserves later map changes from master outside that audit snapshot. Searched open GitHub PRs and issues for related feature-map work. No duplicate cleanup was found. Substantial feature additions retained here include Coordinator (#17983), the agent YAML editor (#18036), document image galleries (#18157), remote workspace storage (#18403), native Kimi (#18391), proactive chat messages (#18374), and the Sentry receiver added in #18714. ## What Changed - Add `rules/feature-map-scope.mdc` and register its `maps/**` scope with Greptile. - Align `AGENTS.md` and the shared map contract with that rule. Routine fixes and test changes no longer require incidental map edits. - Remove 755 net lines from 23 feature recipes. Preserve all 35 areas and 192 capability IDs. - Keep substantial features and the corrections needed for current navigation, provider availability, and access boundaries. Examples from the reviewed changes: | Removed or shortened addition | Why it does not need a feature-map expansion | | --- | --- | | Rounded composer image thumbnails (#18689) | Small UI change within existing task creation. | | Connection profile reads and review-count queries (#18687, #18688) | Performance details within existing app permissions. | | Warm-session, Retry, export-capacity, and tool-wait cases | Regression details for existing execution and recovery. | | New task-search, project-context, document-persistence, and routine test journeys | Test additions for existing capabilities. The tests remain in place. | | New task button placement (#18703) | Another entry to an existing task form. | | Local browser verification notes | Run evidence belongs in the PR or test report. | ## Verification - `node scripts/check-maps.mjs` passes: 35 areas, 192 capability IDs, valid references and contract fields. - `node scripts/storybook-catalog.mjs` passes: 328 files and 3,068 stories. Generated indexes remain ignored. - Compared capability keys and navigation metadata in every edited recipe with the original source. All are unchanged. - Checked rule frontmatter, Greptile registration, representative scope matches, and `git diff --check`. - `pnpm -r typecheck` and `pnpm build` pass on `9a60eef8eb8da9bc7c3a02203c79bec12e8c8b6b`. The final `a0801e8a939494ecde3739097a80258917428e94` commit only corrects two lines in the plugin-panel recipe; map and catalog checks pass again. - Greptile reviewed the final `a0801e8a939494ecde3739097a80258917428e94` head at 5/5 with no findings. The earlier review found one inaccurate phrase about unavailable plugin panels. The hook confirms that readiness gates automatic opening, while declared panels remain selectable. The final documentation commit corrects that phrase and the thread is resolved. Paperclip's refreshed review is advisory and remains queued. - The earlier CI run failed two assertions: [server 4/12](https://github.com/paperclipai/paperclip/actions/runs/41634761842/job/125914173960) counted three Anthropic identity calls instead of two in `connection-management.integration.test.ts`; [chat 1/3](https://github.com/paperclipai/paperclip/actions/runs/41634761842/job/125914174257) observed zero publications instead of one in the same-principal endpoint-settlement case. Both exact tests pass locally on the rebased head. This PR changes neither their source nor their expectations. These failed results remain historical evidence. - Final-head CI passed server 4/12 and all other suites except the first [chat 1/3 attempt](https://github.com/paperclipai/paperclip/actions/runs/41637834618/job/125925926131), which repeated the same zero-publication assertion. The browser gate passed. The single failed-job retry was accepted for this unchanged head in [workflow attempt 2](https://github.com/paperclipai/paperclip/actions/runs/41637834618/attempts/2). [Chat 1/3 passed on that retry](https://github.com/paperclipai/paperclip/actions/runs/41637834618/job/125933199635), and the aggregate verification gate passed. Both required gates, `ci / verify` and `ci / e2e`, are green on `a0801e8a939494ecde3739097a80258917428e94`. The one retry allowance is consumed. - The first full local `pnpm test:run` attempt was interrupted before completion so master could be rebased without changing source under running tests. It is not a passing test result. Full current-head CI remains required. - No application code, tests, schemas, or lockfiles changed. ## Risks - Low runtime risk. This change only edits documentation and review guidance. - Detailed regression instructions become less visible in the feature map. Their tests and technical documentation remain available. - Some additions mix a new feature with a small fix. Those blocks retain the feature and shorten the incidental detail. ## Model Used - OpenAI Codex, GPT-6 family, with reasoning, Git history inspection, repository tools, and code execution. The session does not expose a more specific model deployment ID or 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 — map, catalog, capability-ID, and rule-scope checks; full Vitest limits are stated above - [x] I have added or updated tests where applicable — no new runtime tests apply to this documentation change - [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>
This commit is contained in:
1 parent
17e8bd7735
commit
a61cf38106
27 files changed
+119
-817
No files matched your search
@@ -20,6 +20,13 @@
|
||||
"path": "rules/module-boundaries.mdc",
|
||||
"description": "Module ownership, justification of shared contract changes, delivery scope, and verification across affected consumers."
|
||||
},
|
||||
{
|
||||
"path": "rules/feature-map-scope.mdc",
|
||||
"description": "Limit feature-map additions to substantial new user capabilities; avoid minor-update churn and keep factual corrections minimal.",
|
||||
"scope": [
|
||||
"maps/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "rules/runtime-dependency-boundaries.mdc",
|
||||
"description": "Dependency cost, responsiveness, and verification requirements for changed server, adapter, and runner execution paths.",
|
||||
|
||||
@@ -183,8 +183,11 @@ scope, not proof that a live journey passed.
|
||||
|
||||
The sibling [agent access map](maps/agent-access-map/README.md) records APIs,
|
||||
agent entry points and permission boundaries using the same capability IDs.
|
||||
Follow [the map contract](maps/README.md): update affected entries when mapped
|
||||
behavior or access changes, and run `node scripts/check-maps.mjs` after map edits.
|
||||
Follow [the feature-map scope rule](rules/feature-map-scope.mdc): additions require
|
||||
substantial new features. Routine fixes, polish, refactors, and test changes do
|
||||
not require map updates. Follow [the map contract](maps/README.md) for minimal
|
||||
corrections when existing entries become materially inaccurate, and run
|
||||
`node scripts/check-maps.mjs` after map edits.
|
||||
Its structural checks do not prove live behavior or authorization.
|
||||
|
||||
Storybook has a downstream [feature catalog](maps/storybook-map/README.md).
|
||||
|
||||
+6
-3
@@ -136,9 +136,12 @@ context; source presence alone does not qualify this operation.
|
||||
|
||||
## Keeping the maps synchronized
|
||||
|
||||
When a change adds/removes a capability or changes its behavior, API, permission,
|
||||
tool binding, CLI support, or work mode, update the affected companion and product
|
||||
recipe as appropriate in the same change. Preserve IDs across renames where the
|
||||
Add entries only for substantial new features under the
|
||||
[feature-map scope rule](../rules/feature-map-scope.mdc). Routine fixes, polish,
|
||||
refactors, performance work, and test changes do not require map updates. Correct
|
||||
or remove existing text only when behavior or access changes make it materially
|
||||
inaccurate; keep the correction local to the affected recipe or companion.
|
||||
Preserve IDs across renames where the
|
||||
capability is unchanged; update the affected cross-links together. Indexes discover recipes automatically. An API-only
|
||||
change may update the companion without rewriting unchanged user instructions.
|
||||
Update the corresponding chat scenarios when their request, assumptions or
|
||||
|
||||
@@ -47,17 +47,6 @@ Automated: [activity service](../../server/src/__tests__/activity-service.test.t
|
||||
|
||||
Manual: Find a known mutation by actor/resource and a known run by status. Change filters, load more, and follow the source links. Reload the chosen view and verify no company leakage or duplicate events. Inspect a routine run from its audit entry.
|
||||
|
||||
On a native workspace export failure's run page, choose **Inspect recovery**,
|
||||
then **Inspect current source** on the matching action. Compare the recorded
|
||||
failure with the current recorded-source identity. Inspection is read-only and
|
||||
does not confirm provider termination or file preservation. Resolved retained
|
||||
actions remain inspectable. The control makes no inspection request until used.
|
||||
[Source/HTTP regressions](../../server/src/services/workspace-recovery-source.test.ts)
|
||||
cover current identity, rejected policy, foreign/reused allocation, bounded
|
||||
lookup, redaction and unchanged recovery state; [component regressions](../../ui/src/components/RunWorkspaceRecoverySurface.test.tsx)
|
||||
cover explicit selection, loading, failure and identity-only success. These
|
||||
checks do not establish recovery of a deployed task.
|
||||
|
||||
Case detail's **View in Audit** opens `/activity?entityType=case&entityId=<case UUID>`.
|
||||
The Activity filters include **Cases** actions and **Case** entities; the Case
|
||||
search accepts a UUID or human identifier such as `CAS-C1` (Enter or blur applies
|
||||
|
||||
@@ -33,10 +33,6 @@ Open `/chats`, choose an agent, or use `/chats/:agentRef` and its conversation s
|
||||
|
||||
With Coordinator enabled, the composer exposes the shared model/thinking-level picker for supported agents. The agent stays fixed in this control; switching agents remains in the chat header. Choices save as conversation overrides on send, preserving the agent's configuration. A first message creates the conversation before saving settings and submitting through the ordered comments endpoint.
|
||||
|
||||
Standing chats open with the latest 20 contiguous messages. Scroll upward to fetch earlier messages, answer receipts, and created tasks. The loading indicator stays in the thread; history failures offer an inline Retry while preserving the draft and reading position. Opening a chat does not fetch its lifetime comment, activity, or run history. Already observed messages survive live refresh and Back within the query-cache session.
|
||||
|
||||
Click an agent's name or avatar above a message or active turn to open that agent's overview in the current company. The identity keeps its existing appearance, with no underline on hover. Identities without an agent ID remain plain text.
|
||||
|
||||
Coordinator answer receipts from this conversation jump to the answer bubble without leaving chat. Answer updates from an execution task link to that source task and its decision context. Compact document links read “Open [document title] in the sidebar”.
|
||||
|
||||
### `project-handoff`
|
||||
@@ -53,8 +49,6 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enab
|
||||
|
||||
### `agent-conversation`
|
||||
|
||||
Local browser recipe: [long-chat startup and scrolling](../../tests/perf/agent-chat/agent-chat-startup.spec.ts), with fixture and command details in the [performance README](../../tests/perf/agent-chat/README.md). It covers recent-only reveal, delayed and failed pages, Back, older comment links, and live refresh. Synthetic local data is not deployed acceptance evidence.
|
||||
|
||||
Automated: [chat landing](../../ui/src/pages/AgentChats.test.tsx) checks recent-chat routing; [conversation service](../../server/src/__tests__/agent-conversations.test.ts) covers persisted conversation behavior.
|
||||
|
||||
Automated: [proactive delivery](../../server/src/__tests__/agent-chat-messages.test.ts)
|
||||
@@ -67,15 +61,6 @@ qualify live PR retrieval or a model's editorial choices.
|
||||
|
||||
Automated: [composer picker](../../ui/src/components/task-chat/ComposerRunSettingsPicker.test.tsx) covers fixed-agent model/effort selection on desktop and mobile; [composer](../../ui/src/components/task-chat/TaskChatComposer.test.tsx) covers Coordinator gating and settings submission without reassignment. [Task detail](../../ui/src/pages/IssueDetail.test.tsx) verifies canonical first/existing-chat IDs, settings-before-comment ordering, and no comment submission when settings fail to save. These tests mock the API and do not prove provider execution with the chosen model.
|
||||
|
||||
Automated: [conversation delivery](../../server/src/__tests__/agent-conversation-delivery.test.ts)
|
||||
checks that paused or otherwise non-invokable agents leave comments pending
|
||||
without aborting startup recovery, and that a later unpause allows one delivery.
|
||||
The test persists queue admissions only; it does not start agents or providers.
|
||||
Automated: [historical chat](../../ui/src/pages/AgentChat.test.tsx) keeps an older
|
||||
conversation reachable after a cached roster refresh ends in HTTP 429. It checks
|
||||
lookup Retry and preserves permission and company boundaries. This is component
|
||||
evidence with real query state, not live provider proof.
|
||||
|
||||
Automated: [thread and composer](../../ui/src/components/TaskChatThread.test.tsx)
|
||||
keeps an in-flight attachment through first-chat creation on desktop and mobile,
|
||||
while initial history for an existing conversation stays deferred. The
|
||||
@@ -88,7 +73,6 @@ send. Confirm the same file stays in the composer after the chat is created.
|
||||
Send it once, reload, and confirm the file and message remain.
|
||||
|
||||
Manual: Start a conversation, send a recognizable request, and inspect its reply.
|
||||
Click the responding agent's name, return with Back, then click its avatar; both should open that agent's overview without changing companies. Check that the identity looks unchanged at rest and on hover on desktop and mobile.
|
||||
Navigate away and reopen the same history. Use `/new` for a fresh session within
|
||||
the same standing conversation. Test an unavailable historical agent and an
|
||||
inaccessible saved conversation; verify no cross-user or cross-company history appears.
|
||||
@@ -136,8 +120,6 @@ Manual: Check disabled access first, enable in the disposable instance, then sen
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Coordinator Markdown references to a standing agent conversation display “Chat with [agent]” and route to that chat, preserving anchors. Labels resolve once from the existing current-person/current-company chat list and agent roster; no task status glyph or task quicklook is shown for these references. Ordinary task links retain their existing treatment.
|
||||
|
||||
- Idle chat is not failed execution.
|
||||
- See [steering](./steering.md) for in-flight messages and [questions](./questions-and-approvals.md) for interactions.
|
||||
- An API tool test does not prove that every harness will choose the same handoff tool.
|
||||
|
||||
@@ -34,15 +34,8 @@ Use New agent from the roster or `/agents/new`.
|
||||
Submitting the name creates an inactive record before adapter selection or account setup.
|
||||
A name-only draft returns to adapter selection when reopened.
|
||||
Save & exit keeps its configuration; Finish setup on the agent returns to the
|
||||
same record. Open an unfinished agent from the roster to reach its header.
|
||||
The header shows Finish setup instead of Run or Resume, including during computer
|
||||
preparation and verification. Terminating agents cannot reopen setup. Final
|
||||
submission requests approval when required, then follows the existing preparation
|
||||
and verification lifecycle.
|
||||
The confirmation shows **Finishing agent setup** until the foreground detail
|
||||
query observes actual readiness. **Assign a Task** then hands that current
|
||||
record to the composer, so its status does not come from an older paused draft.
|
||||
Manual/import pauses and required hire approval remain blocking states.
|
||||
same record. Final submission requests approval when required, then follows the
|
||||
existing preparation and verification lifecycle.
|
||||
|
||||
When the native Runner adapter is available, **Google Antigravity** appears in the ordinary
|
||||
adapter picker. Before runtime acceptance, its card says **Not available yet**.
|
||||
@@ -64,16 +57,6 @@ Test verifies native account/model admission and cleanup without a model turn.
|
||||
Other companies, remote targets, expired authority and other models stay blocked.
|
||||
Verify this scoped path separately from production qualification and real task acceptance.
|
||||
|
||||
The explicit-only [Antigravity agent journey](../../tests/runner-e2e/ANTIGRAVITY-AGENT-JOURNEY.md)
|
||||
protects the ordinary roster/picker path, saved personal Google subscription,
|
||||
native Test, actual ready handoff, Instructions-only file marker, task and
|
||||
same-task follow-up. Its fixed driver starts from the dashboard and creates the
|
||||
new agent through visible controls. The current runnable cell attaches to a
|
||||
self-hosted target with the admitted local macOS ARM64 candidate and exact low
|
||||
model. Saved-account reuse does not qualify fresh OAuth, other platforms or
|
||||
global provider release; registration and synthetic controls are separate from
|
||||
the retained exploratory and fresh fixed-driver results.
|
||||
|
||||
Agent-owned plugin environments prepare the saved draft in the background when
|
||||
their driver declares `requiresAgent`. The draft waits in `verifying` with its
|
||||
setup hold until hiring finishes. Changing environments keeps the selected
|
||||
@@ -151,9 +134,8 @@ replacement confirmation. The Chat agent picker opens a conversation; it does
|
||||
not set the person's primary preference. This guidance grants no agent write
|
||||
authority.
|
||||
|
||||
Open an agent profile and choose the outlined crown beside its name (**Set as my
|
||||
primary**). Inspect the filled crown on the profile, the crown on the roster and
|
||||
its position in the Agents sidebar, then open a new task or Chat.
|
||||
Open an agent profile and choose **Set as my primary**. Inspect its crown on the
|
||||
profile/roster and its position in the Agents sidebar, then open a new task or Chat.
|
||||
|
||||
### `agent-api-keys`
|
||||
|
||||
@@ -175,9 +157,6 @@ For an agent-owned plugin environment, verify preparation before connecting,
|
||||
same-agent probes, account preservation after an environment change, failed
|
||||
selection-save retry, and switching back while the computer stops. Confirm the
|
||||
setup hold still blocks ordinary work and API key creation before finishing.
|
||||
Start through the name/adapter dialog with a managed-only or forced Kubernetes
|
||||
policy and a draft that inherits its environment. Once preparation completes,
|
||||
confirm the auth choices, Advanced gateway, and saved subscription remain usable.
|
||||
The [setup lifecycle tests](../../server/src/modules/agent-lifecycle/__tests__/setup.test.ts)
|
||||
exercise durable transitions with synthetic plugin resources; they do not prove
|
||||
live VM provisioning.
|
||||
@@ -235,9 +214,7 @@ Manual: Save a harmless instruction edit, reload, and verify its revision and ef
|
||||
|
||||
For failed setup, use an unavailable model or invalid command on a disposable agent.
|
||||
Confirm the profile names the failed verification step and gives a relevant action.
|
||||
Check that a failed configuration test explains that automatic verification is paused
|
||||
and offers **Retry now**. Repeated refreshes must not start another test. Timeouts
|
||||
and temporary test-environment failures still retry automatically. Fix the configuration,
|
||||
Check that it explains that verification is paused and offers **Retry now**. Fix the configuration,
|
||||
retry, and reload; the failure must disappear only after readiness commits.
|
||||
Provider output and credentials must not appear in the lifecycle message.
|
||||
|
||||
@@ -254,10 +231,6 @@ pending edits and an environment-variable draft. An unsaved change to a differen
|
||||
effective computer must disable the action and explain that the computer change
|
||||
must be saved first; restoring the saved target must re-enable it. Reopen the page and compare the
|
||||
saved harness, model, account bindings, instructions, and run policy. Check a
|
||||
Grok upgrade with an unset or `grok-build` model: it must use `grok-4.7`.
|
||||
Compare effective search policy before and after, including the implicit disabled
|
||||
default and explicit enabled search. Verify task model and effort changes use the
|
||||
Grok catalog and reach execution while retaining the account and search policy. Check a
|
||||
saved `maxTurnsPerRun: 1000`: upgrade must warn and remove it. Test an initially
|
||||
unqualified Daytona Paperclip Computer: click must probe, record qualification,
|
||||
refresh availability, and only then save. A failed probe or changed selection must
|
||||
@@ -294,10 +267,9 @@ Manual: Inspect a manager and report, change the relationship through the offere
|
||||
|
||||
### `personal-primary-agent`
|
||||
|
||||
Automated: [primary-agent context](../../ui/src/context/PrimaryAgentProvider.test.tsx),
|
||||
[the profile crown](../../ui/src/components/primary-agent/PrimaryAgentPresentation.test.tsx)
|
||||
Automated: [primary-agent context](../../ui/src/context/PrimaryAgentProvider.test.tsx)
|
||||
and [primary-agent routes](../../server/src/__tests__/primary-agent.test.ts)
|
||||
cover selection, replacement confirmation, company/user scope, and request contracts.
|
||||
cover selection, company/user scope, and request contracts.
|
||||
|
||||
Manual: Select an available agent, reload, and inspect the retained personal choice.
|
||||
Replace it and verify confirmation is required. Leave or terminate the selected
|
||||
|
||||
@@ -27,12 +27,6 @@ that new approval before execution. Retries of the declined intent and its
|
||||
rejection continuation remain declined. Missing or untrusted human provenance
|
||||
does not open another review.
|
||||
|
||||
Changing the connection's agent list preserves profile assignments for agents
|
||||
that remain installed. Saving the list must not restore a removed app-profile
|
||||
assignment. New installations retain the current app-profile defaults.
|
||||
Non-empty saves also remove legacy connection-wide include rules, including
|
||||
unchanged lists and removals with no new targets.
|
||||
|
||||
## How to get to it (user POV)
|
||||
|
||||
### `permissions`
|
||||
@@ -56,18 +50,8 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Prep
|
||||
|
||||
### `permissions`
|
||||
|
||||
The page loads saved profiles for the displayed connection through the configuration read. It preserves complete app bindings for saves and the install fallback when bindings are empty. It does not request profile summaries or pending-review counts.
|
||||
|
||||
Automated: [app detail](../../ui/src/pages/apps/AppDetail.test.tsx) covers agent/action controls, quarantined actions, and navigation using mocked requests.
|
||||
|
||||
[Installation permission regressions](../../server/src/__tests__/tool-connection-installs.test.ts)
|
||||
exercise the real install API with a local operator and PostgreSQL. They check
|
||||
that adding, removing, or retaining agents preserves removed app-profile grants
|
||||
and denies write tools for agents with read-only profiles. They also check
|
||||
company installations, new-agent defaults, legacy connection-wide include
|
||||
cleanup, and access-extension audit records.
|
||||
These fixtures do not qualify an agent-authenticated request or a live provider.
|
||||
|
||||
[Runtime assignment tests](../../server/src/__tests__/agent-runtime-assignments.test.ts)
|
||||
use PostgreSQL to verify committed assignment notifications, bounded snapshots,
|
||||
rollback, and concurrent AI adoption. The owning lifecycle plugin can read
|
||||
@@ -106,20 +90,6 @@ still need live account qualification.
|
||||
|
||||
Automated: [app detail tests](../../ui/src/pages/apps/AppDetail.test.tsx) cover test-dialog/UI contracts. Real provider execution and revocation require the selected provider’s live check.
|
||||
|
||||
AI account details share the Permissions page's grants query. Account and grants
|
||||
reads have a 15-second deadline. The AI panel retries a transient failure once,
|
||||
then shows an error with Retry. A background failure keeps loaded controls visible.
|
||||
[AI account loading tests](../../ui/src/components/ai-connections/ManagedAiConnectionDetails.test.tsx)
|
||||
exercise stalled account/grants reads, cancellation, retry recovery and cached grants.
|
||||
|
||||
The account-details section shows the provider email and organization when
|
||||
available, beside the sign-in method and Paperclip ownership. Anthropic profile
|
||||
permission denial shows an explicit unavailable message without changing the
|
||||
connection's connected state. Account identity loads independently of maintenance
|
||||
controls, has a bounded wait and a separate retry for temporary failures, and
|
||||
is refreshed after a credential grant changes. [Account-details tests](../../ui/src/components/ai-connections/AiConnectionAccountDetails.test.tsx)
|
||||
cover these states and prevent one grant's email from appearing for another.
|
||||
|
||||
Manual: Run a read-only action with explicit inputs and inspect returned data and activity. Refresh discovery and review new actions. Revoke or disconnect only the disposable credential, then verify subsequent use fails with an actionable reconnect state.
|
||||
|
||||
For Daytona, opening an older saved catalog discovers the current native
|
||||
@@ -169,9 +139,3 @@ Sources: Source: [PermissionsPanel.tsx](../../ui/src/pages/apps/app-detail/Permi
|
||||
### `delegated-configuration`
|
||||
|
||||
See the canonical [delegated configuration guidance and acceptance evidence](connection-setup.md#delegated-configuration).
|
||||
|
||||
The contextual connection sidebar reads only the selected connection's pending
|
||||
signed action request and quarantined action counts. Its Review badge is the
|
||||
pending request count plus one when any action is quarantined. It refreshes every
|
||||
30 seconds and after existing attention invalidations. Archived connections show
|
||||
no badge. The full Apps attention view keeps its existing company-wide read.
|
||||
@@ -29,14 +29,12 @@ Message the configured bot/address from its external provider and follow the cor
|
||||
|
||||
### `endpoint-management`
|
||||
|
||||
Delegated setup can save ordinary bot tokens and API keys. Provider verification keys require the addressed human credential-entry step or verified provider provisioning. Generic setup returns the saved handoff without changing those keys, and generic connection updates cannot replace channel credential references. A replacement card waits for an actual protected-value change and restored verification; old health, unchanged entry and unrelated bot-token repair do not complete it. Fresh GitHub handoffs open the import form; configured endpoints retain reconnect. Credential-entry field sets and completion modes stay distinct while matching retries reuse their saved baseline. Complete human replacements can repair disabled, deleted or unreadable old vault values. Saved links name the requested fields and completion mode; configured GitHub forms support targeted replacements while keeping other saved credentials. Provisioned Slack challenge proof survives runtime storage only for the same signing key and callback URL. The actual-auth Slack/GitHub fixtures cover these boundaries, retries, revocation and permitted bot-token repair; live provider repair remains separately qualified.
|
||||
Delegated setup can save ordinary bot tokens and API keys. Provider verification
|
||||
keys require the addressed human credential-entry step or verified provider
|
||||
provisioning. Open the saved setup link as that person to complete the request.
|
||||
|
||||
Open `/apps/chat/:endpointId/settings` and the endpoint’s other available tabs; identity confirmation uses `/chat-identity/confirm`.
|
||||
|
||||
For GitHub external contributors, open the connection's Access tab and look up a username. The lookup uses that endpoint's active GitHub App installation with a metadata-only token. Verify that a person or bot resolves to its numeric identity and that unavailable accounts, rate limits, and installation failures show distinct errors. [Lookup regressions](../../server/src/services/chat-github-management.test.ts) use provider fixtures; live installation lookup remains separate evidence.
|
||||
|
||||
For delegated Slack test messages and identity invitations, apply a Block or Ask first rule to the calling agent while allowing the endpoint's assigned agent. Verify no message is sent. Exercise caller, target and shared rate limits: one shared quota admits one send and the next distinct request is denied. For a saved GitHub identity handoff on an otherwise healthy endpoint, verify the card stays pending before identity confirmation and after an OAuth callback alone. Confirm the addressed user's identity through their human session, then verify continuation becomes available. Revoked, expired, wrong-user and wrong-installation links must keep the handoff blocked. These cases pass through the assembled API with real key/JWT/session middleware and deterministic providers; live Slack/GitHub consent remains separate evidence.
|
||||
|
||||
### `outbound-agentmail`
|
||||
|
||||
Use `paperclipai email inboxes --company-id <company-id>`, then `email send --company-id <company-id> --file <new-email.json>` or `email reply --company-id <company-id> --file <reply.json>`. Inspect `email thread <email-task-id> --company-id <company-id>` and `email delivery <publication-id> --company-id <company-id>`. Agent mutations must provide --run-id or the active PAPERCLIP_RUN_ID.
|
||||
@@ -49,17 +47,6 @@ AgentMail bypasses the chat-connectors UI gate, GitHub uses
|
||||
`enableGitHubReviewBots`, and other chat providers use `enableChatConnectors`.
|
||||
Setup is covered in [connection setup](./connection-setup.md).
|
||||
|
||||
For managed Slack setup, resume a saved draft with an authorized workspace and
|
||||
choose Continue. Verify it creates and installs the bot once. The HTTP route
|
||||
must resolve the selected Slack manager grant, reject malformed or missing IDs,
|
||||
and deny another company's or person's grant before provider calls. The channel
|
||||
integration suite exercises this route with a board fixture and provider fixtures;
|
||||
live Slack setup remains a separate acceptance check.
|
||||
After welcome delivery completes setup automatically, verify **Open Slack**
|
||||
remains on Success and on the saved connection page. Follow that visible link,
|
||||
send a real DM and thread follow-up, then reload the catalog to confirm setup
|
||||
stays complete. A welcome message alone is not an agent response.
|
||||
|
||||
### `external-thread`
|
||||
|
||||
Automated: [channel integration](../../server/src/__tests__/chat-channels.integration.test.ts) uses provider fixtures; it does not prove a live Slack, Discord, Teams, Telegram, GitHub, email, or Photon delivery.
|
||||
@@ -195,23 +182,14 @@ provider responses. Verify actual credential validity and restored delivery
|
||||
separately against GitHub; a Storybook success does not establish live recovery.
|
||||
|
||||
For an agent-requested GitHub credential handoff, open the saved link as the
|
||||
addressed human and verify it asks for exactly the requested fields and all/any
|
||||
completion mode. A fresh App opens import; a configured App opens replacement
|
||||
through reconnect and retains credentials omitted from the request. Interrupt
|
||||
the response after a successful rotation, reload, and verify the saved rotation
|
||||
resumes without replacing the key again. Wrong-user access, unchanged credentials
|
||||
and missing verification must not complete the request. After OAuth, confirm the
|
||||
addressed user's exact endpoint identity before expecting task continuation.
|
||||
addressed human. A fresh App opens import; a configured App opens replacement
|
||||
through reconnect and retains credentials omitted from the request. Complete
|
||||
the requested credential entry and confirm the endpoint identity before
|
||||
expecting task continuation.
|
||||
|
||||
For GitHub, submit a disposable PR and verify the summary heading uses the bot's
|
||||
display name and the check remains **Paperclip Review**. For two separate bots on one PR, verify
|
||||
their App-scoped checks and comments remain independent.
|
||||
For a newly configured bot, verify `submit_review` describes body-only summary
|
||||
and rationale fields. Submit a summary with repeated current-bot or legacy
|
||||
score headings, including an old score; verify publication keeps one heading
|
||||
with the structured score, preserves findings and rationale, and retains the
|
||||
original assessment. The PostgreSQL-backed publication fixture covers this with
|
||||
simulated GitHub responses; live model compliance remains separate evidence.
|
||||
|
||||
For GitHub publication recovery, interrupt a response after GitHub accepts a
|
||||
write and verify one summary, finding, and App-scoped check. Retry the same tool
|
||||
@@ -289,32 +267,6 @@ After successful admission, reload and verify that the prior skipped receipt doe
|
||||
not strand a later real provider reply or tree resume. Provider fixtures support
|
||||
this behavior; live fixed-source runtime and destination proof remain separate.
|
||||
|
||||
Also complete an older review successfully while a newer authorized PR event
|
||||
remains deferred. Use Retry and verify that the existing saved-input receipt
|
||||
starts exactly one new turn, repeated clicks share that turn, and the older
|
||||
accepted result remains unchanged. Revoke the connection or change the source
|
||||
binding before dispatch and verify no run starts. Keep prior cleanup pending,
|
||||
then settle it and verify the same receipt resumes once. These database-backed
|
||||
provider fixtures do not establish live GitHub publication at the fixed revision.
|
||||
|
||||
Also defer Retry behind cleanup, queue an independent board message, then
|
||||
complete cleanup. Verify one run receives the exact GitHub batch and the board
|
||||
message enters its own turn. For an older mixed batch rejected before provider
|
||||
startup, ordinary task Retry must recover only certified undelivered receipts.
|
||||
Changed input, active ownership, allocations and prior delivery must keep the
|
||||
refusal effective. Check the restoration audit and unchanged failed-run history.
|
||||
|
||||
### `delegated-configuration`
|
||||
|
||||
Endpoint activity hides private-task events while retaining a next-page cursor across private-only windows, so older readable history stays reachable. Actual-JWT fixtures verify this separately from live provider delivery.
|
||||
|
||||
See the canonical [delegated configuration guidance and acceptance evidence](connection-setup.md#delegated-configuration).
|
||||
|
||||
GitHub finding category contract (2026-10-31): manual and automatic review
|
||||
instructions list the repository policy categories. `begin_review` returns the
|
||||
assessment snapshot's `findingCategories`; later settings do not change that
|
||||
snapshot. Submit an unknown category and confirm rejection before publication,
|
||||
then submit a listed custom category and inspect the saved assessment and
|
||||
processed publication. The channel integration fixture covers real PostgreSQL
|
||||
and the service path with simulated GitHub HTTP; live model behavior remains
|
||||
unverified.
|
||||
@@ -253,18 +253,6 @@ remain. Complete the step, verify the exact task continues, and confirm that
|
||||
revoked authority or cancelled work prevents continuation. An ordinary bot-token
|
||||
repair or an unchanged credential must not complete a signing-key request.
|
||||
|
||||
For Google, request a specific service set, leave and reopen setup, and inspect
|
||||
the addressed user's pending choices. Another user's or organization grant must
|
||||
not supply those choices. A newer actual consent supersedes the saved request;
|
||||
a token refresh does not. A failed grant read must not broaden the selection.
|
||||
For Vercel personal setup, verify the selected credential belongs to the
|
||||
responsible person and new bindings record the configuring human as creator.
|
||||
Agent-initiated API changes retain the acting agent in audit; the human callback
|
||||
retains its actual human actor.
|
||||
Use the [chat endpoint recipe](chat-channels.md#endpoint-management) for GitHub
|
||||
field-specific credential entry and saved rotation recovery, and the
|
||||
[model-account recipe](runs-adapters.md#managed-account-setup) for AI sign-in.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- For connecting an assistant to Paperclip itself, use [Assistant connections (MCP)](./assistant-connections.md). This recipe's MCP-link journey connects Paperclip to an external app server.
|
||||
|
||||
@@ -28,12 +28,8 @@ Open a document from the task thread or document side panel.
|
||||
|
||||
To create or edit a general task document, open **Open a new tab → Artifacts**
|
||||
in the task side panel, then **New document** or **Document actions → Edit
|
||||
document**. Edits use the shared versioned editor and autosave. Classic mode
|
||||
keeps that editor in the task body. Plans retain their conversation and approval
|
||||
flow and cannot be created through the general document editor.
|
||||
Unfinished new documents, including a body typed before its key, survive a tab
|
||||
switch or reload within the same account and task. Cancel removes the backup;
|
||||
a confirmed creation clears it.
|
||||
document**. Classic mode keeps the editor in the task body. Plans retain their
|
||||
conversation and approval flow.
|
||||
|
||||
Select an inline image to open the document's image gallery. Use the left and
|
||||
right arrow keys or the Previous and Next buttons to move through images in
|
||||
@@ -63,15 +59,6 @@ Open `/artifacts` and its grouping, search, and media controls.
|
||||
|
||||
## Driving it with Playwright and the Paperclip CLI
|
||||
|
||||
The explicit `build-revise` [Product journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md) covers `documents-artifacts/attachments`: browser downloads of two ZIP versions, an independent content oracle, and preservation of the original. Its shared source is not proof of a pass on any deployed target.
|
||||
|
||||
The explicit `task-document-persistence` journey covers `documents-artifacts/documents`:
|
||||
browser creation and editing, task reopen/reload, exact saved title/body and
|
||||
independent original/latest revision reads, board-user authorship and zero agent
|
||||
runs. The setup owns a backlog task but does not seed a document. Calibration
|
||||
rejects stale content, lost history and foreign ownership. A target needs a fresh
|
||||
live pass before adding this journey to its scheduled checks.
|
||||
|
||||
Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a task with a text document, a small attachment, and a generated work product. Use nonsensitive fixture files.
|
||||
|
||||
### `task-document`
|
||||
@@ -94,18 +81,6 @@ Manual: Edit a paragraph, save, reload, and compare revisions. Add an annotation
|
||||
|
||||
Automated: [attachment routes](../../server/src/__tests__/issue-attachment-routes.test.ts) and [work products](../../server/src/__tests__/work-products.test.ts) cover data/access behavior; [artifact arrival browser suite](../../tests/e2e/artifact-tab-arrival.spec.ts) targets arrival. [Artifact uploads](../../tests/e2e/artifact-uploads.spec.ts) drives file selection/drop, filename collisions, retry, and preservation of paused/unassigned tasks.
|
||||
|
||||
The deployment-targeted [uploaded-input journey](../../tests/runner-e2e/product-journeys/input-file-flow.ts)
|
||||
adds composer upload, real agent consumption, independent calculation, attributed
|
||||
saved output and reload checks. Registration and oracle controls do not establish
|
||||
a live pass on a deployment.
|
||||
|
||||
[Native completion feedback](../../server/src/services/native-runtime/native-completion-feedback.test.ts)
|
||||
checks a real saved-document link alongside a verified CSV attachment, including
|
||||
attachment download query and fragment links. It rejects foreign task/company
|
||||
links, missing documents, unproven current revisions, and workspace files. The
|
||||
document alone cannot satisfy the requested file. These local tool/Postgres
|
||||
checks do not establish hosted delivery or browser rendering.
|
||||
|
||||
Manual: Upload a small Markdown file and CSV through Artifacts. Markdown becomes
|
||||
a versioned task document; other files become attachments. Read the document,
|
||||
download the CSV and compare bytes, then reload. Upload the same Markdown filename
|
||||
@@ -122,8 +97,6 @@ Manual: Find the task’s output through search and grouping, open its stack, pa
|
||||
|
||||
## Gotchas
|
||||
|
||||
- In Coordinator, saved plan cards use document chronology, so a plan written before its output appears first even when both writes share one native run. Authored issue-document links use the same compact sidebar-link surface and retain revision/annotation targets. Classic run embedding is unchanged. The UI does not remove or deduplicate canonical plan content.
|
||||
|
||||
- A local path is not automatically an uploaded artifact accessible to another user.
|
||||
- A preview screenshot is not proof that download bytes or revision references are correct.
|
||||
- Version conflicts and stale annotations must stay visible rather than silently targeting different content.
|
||||
|
||||
@@ -53,14 +53,9 @@ and its diagnostic in the probe result: connection success alone does not mean
|
||||
the image has native runtime qualification.
|
||||
|
||||
Paperclip-managed Cloud images use the current platform-selected image without
|
||||
a saved qualification prerequisite. A missing, stale or revoked qualification
|
||||
does not block execution or pin an older snapshot. Runtime startup and the
|
||||
handshake detect real incompatibility. This exception excludes custom
|
||||
environments and active captured custom images.
|
||||
The active Cloud configuration must provision the sandbox provider. A stale
|
||||
managed marker alone keeps the normal qualification rules.
|
||||
An outdated captured image that execution ignores must not block discovery of
|
||||
the current managed image. A matching custom capture keeps qualification.
|
||||
a saved qualification prerequisite when the active Cloud configuration provisions
|
||||
the sandbox provider. Custom environments and active captured custom images
|
||||
retain qualification requirements.
|
||||
|
||||
For other images, the measured record is server-owned, company-bound and tied to the effective
|
||||
configuration and active custom-image identity. Mutable tags, provider defaults
|
||||
@@ -81,11 +76,6 @@ qualification is not reused. A mutable-image connection can succeed while
|
||||
qualification remains absent. Assert ordinary agent and non-admin board probe
|
||||
requests are denied, and environment create/PATCH payloads cannot supply
|
||||
qualification metadata.
|
||||
For a managed Cloud image, replace the platform-selected snapshot while an old
|
||||
qualification remains. Discovery must still offer Paperclip Runner, and Test
|
||||
must check the runtime directly. Verify execution selects the replacement image
|
||||
and still reports a real provider startup failure. Keep a custom-image control
|
||||
that requires its existing qualification.
|
||||
This recipe and its [probe controls](../../server/src/__tests__/environment-probe.test.ts)
|
||||
are not claims that a live provider or agent-access journey ran for this map update.
|
||||
|
||||
@@ -105,11 +95,9 @@ data transfer is outside task execution. See the
|
||||
The [fake-provider integration](../../server/src/__tests__/plugin-runner-task.integration.test.ts)
|
||||
checks acquisition, SDK dispatch, scope denial, stop proof and deletion recovery.
|
||||
Its WebSocket is mocked; it does not qualify a live provider or a real Runner handshake.
|
||||
Controller replacement reuses a surviving plugin task's active lease and exact
|
||||
Runner identity. The integration checks reconnect without prepare, submit, or
|
||||
stop. The [continuity recipe](../../doc/testing-native-remote-continuity.md#replacing-the-main-server)
|
||||
also covers real-process recovery after controller files are removed; deployed
|
||||
plugin and Daytona acceptance require their own evidence.
|
||||
Controller replacement reuses a surviving plugin task's active lease and Runner
|
||||
identity. Follow the [remote continuity recipe](../../doc/testing-native-remote-continuity.md#replacing-the-main-server)
|
||||
to verify recovery across main-server replacement.
|
||||
|
||||
For a same-run retry on a replacement plugin task, verify that the retained
|
||||
checkpoint loads before provider startup. The prior execution must have a stop
|
||||
@@ -142,10 +130,6 @@ uses the real Runner and a synthetic Codex provider through loopback PRP; TLS
|
||||
termination is replaced by the fixture. It does not qualify a live plugin provider.
|
||||
|
||||
The plugin prepares execution-host resources and the provider descriptor. Core validates the result, then supplies task identity and PRP launch limits.
|
||||
For managed GitHub commands, verify the qualified executable remains canonical,
|
||||
controller-staged helper discovery survives task entry, and a task-supplied shell
|
||||
selector is rejected. A launch description or a healthy Runner alone is not proof
|
||||
of authenticated git/gh execution.
|
||||
|
||||
### Storybook verification
|
||||
|
||||
@@ -189,11 +173,3 @@ Managed account transfer requires `projectAuthCheckVersion: 1` and a successful
|
||||
`check_project_auth` result for the exact prepared configuration, provider, and
|
||||
project set. New preparation removes old validation. Core checks the saved
|
||||
validation again in the dispatch update.
|
||||
|
||||
Plugin task providers can advertise `githubCredentialBrokerVersion: 1` and receive
|
||||
a live-run capability during preparation. This adds no agent management API.
|
||||
Core resolves accepted identity, grants, company scope and trust at command time.
|
||||
The plugin owns the command implementation; no particular script is required.
|
||||
[Broker handoff coverage](../../server/src/services/native-runtime/plugin-runner-task.test.ts)
|
||||
checks capability changes across warm turns. This is contract coverage, not live
|
||||
authenticated push acceptance.
|
||||
@@ -67,13 +67,6 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Seed
|
||||
|
||||
Automated: [archive routes](../../server/src/__tests__/inbox-archive-routes.test.ts) cover server mutations. [Task-list helpers](../../ui/src/pages/Issues.test.tsx) cover search URLs, pagination, and presentation constants; they do not render the combined Inbox/Tasks page. Reading, archiving, and navigating that page remain manual checks.
|
||||
|
||||
The deployment-targeted [personal-triage journey](../../tests/runner-e2e/product-journeys/inbox-triage-flow.ts)
|
||||
drives Mark as read and Archive, reloads Unread and Mine, independently verifies
|
||||
unchanged task status, and observes a later Blocked transition resurface the item.
|
||||
It uses one owned self-assigned task and no agent work; its registration is
|
||||
separate from a measured Cloud pass. Other actors and company boundaries remain
|
||||
separate verification cases.
|
||||
|
||||
Automated: [Issue service regressions](../../server/src/__tests__/issues-service.test.ts)
|
||||
cover exclusion of historical automatic read cleanup from user participation,
|
||||
unread counts, and activity timestamps while retaining explicit user decisions
|
||||
@@ -98,22 +91,7 @@ Cold-open verification: load Mine with the task-index response delayed while
|
||||
approvals/runs resolve. Only the stable list placeholder should appear until the
|
||||
initial sources settle; a failed-run row must not jump when tasks arrive. Release
|
||||
visible-row details separately and compare row/title bounds. Mine reads its own
|
||||
100-row index. Missing parents use the same index projection for their captions;
|
||||
parents already in the index are reused. Failed-run tasks still load rich row
|
||||
context by ID, including when they are also parents or already indexed, so resolved
|
||||
interruptions stay hidden. The initial reveal waits for both context sources.
|
||||
Sidebar badges use the count endpoint.
|
||||
Coordinator desktop and mobile navigation share `/attention/summary` for the
|
||||
outstanding count. Needs You owns its complete feed; Tasks → Needs attention
|
||||
owns a compact complete task-ID index. Navigation reuses either page response. Coordinator keeps the optimized Inbox even when
|
||||
the instance Streamlined UI setting is off. The loopback browser checks in
|
||||
[collection startup](../../tests/perf/collections/startup.spec.ts) exercise these
|
||||
reads and the initial task row budget. They do not establish deployed latency.
|
||||
Collection startup selects the addressed active organization before starting
|
||||
company reads. Shared controls load separately from task detail. A painted
|
||||
collection or task-link intent starts a low-priority code fetch; direct task URLs keep
|
||||
early module preload. The collection
|
||||
browser cases cover a remembered different organization and failed speculation.
|
||||
100-row index, with parent/run context by ID; sidebar badges use the count endpoint.
|
||||
The [Inbox component checks](../../ui/src/pages/Inbox.test.tsx) cover the source
|
||||
barrier and selected-source query; [badge tests](../../server/src/__tests__/inbox-dismissals.test.ts)
|
||||
cover unread counts. Browser timing and layout proof remain separate from these tests.
|
||||
@@ -210,5 +188,3 @@ Scope: ui
|
||||
Storybook: Eligible live task toast, explicit mention, quiet unrelated event, own-action/visible-task suppression, dedupe and company/account switch.
|
||||
Production: Persisted participation and mentions determine per-viewer socket eligibility; quiet events still refresh caches; reload retains eligibility, unauthorized resources remain denied.
|
||||
Sources: Source: [ToastViewport.tsx](../../ui/src/components/ToastViewport.tsx), [ToastContext.tsx](../../ui/src/context/ToastContext.tsx), [LiveUpdatesProvider.tsx](../../ui/src/context/LiveUpdatesProvider.tsx), [task-toast-eligibility.ts](../../server/src/realtime/task-toast-eligibility.ts). Tests: [ToastContext.test.tsx](../../ui/src/context/ToastContext.test.tsx), [ToastViewport.test.tsx](../../ui/src/components/ToastViewport.test.tsx), [LiveUpdatesProvider.hook.test.tsx](../../ui/src/context/LiveUpdatesProvider.hook.test.tsx), [task-toast-eligibility.test.ts](../../server/src/__tests__/task-toast-eligibility.test.ts), [live-events-toast.test.ts](../../server/src/__tests__/live-events-toast.test.ts), [multi-user-authenticated.spec.ts](../../tests/e2e/multi-user-authenticated.spec.ts)
|
||||
|
||||
Coordinator navigation counts all outstanding canonical attention items on desktop and phone, using the same complete feed as Needs You. Classic keeps its existing today-oriented badge. Task questions resolve through their original interaction; pending chat projections, counts and recorded receipts invalidate together.
|
||||
@@ -67,27 +67,8 @@ served by the admitted application before it finishes. Repeat with a disconnect
|
||||
before headers arrive. Confirm that neither leaves a permanent request hold. An
|
||||
unfinished application write must still prevent sleep after its client leaves.
|
||||
|
||||
Automated: [historical cleanup](../../server/src/__tests__/historical-cleanup-verification.test.ts)
|
||||
exercises the runtime inspection path for failed Cloud sandbox leases, including
|
||||
verification leases without a run. A signed cleanup-only absence observation
|
||||
can remove this blocker without changing failed outcomes or granting run
|
||||
continuation. An unresolved provider resource still prevents idle sleep.
|
||||
Manual: on an owned Cloud staging workspace, confirm the exact published build,
|
||||
reconcile failed test allocations, then verify actual provider suspension and
|
||||
normal hosted entry after wake. Local tests do not prove that hosted journey.
|
||||
|
||||
### `settings-backup`
|
||||
|
||||
Cloud startup reads nonsecret application choices from a private, versioned
|
||||
PostgreSQL singleton after a bounded one-time legacy config seed. A fresh
|
||||
process and different home restore the saved choices without consulting a stale
|
||||
`.env` file. Invalid saved data or an unavailable database prevents startup;
|
||||
saved telemetry opt-out applies before client creation. The
|
||||
[database controls](../../server/src/__tests__/cloud-runtime-config.test.ts) and
|
||||
[startup-order controls](../../server/src/__tests__/server-startup-feedback-export.test.ts)
|
||||
cover these local boundaries. See [field ownership](../../doc/cloud-runtime-configuration.md).
|
||||
These controls do not qualify a deployed Cloud rollout or durable file storage.
|
||||
|
||||
Automated: [experimental settings](../../ui/src/pages/InstanceExperimentalSettings.test.tsx) and [database backup routes](../../server/src/__tests__/instance-database-backups-routes.test.ts) cover their UI/API contracts.
|
||||
|
||||
Cloud migration: in one maintenance window, stop legacy file writers and run the
|
||||
@@ -100,16 +81,6 @@ configuration/packages and does not qualify whole-server zero downtime, secret
|
||||
bytes, or volume removal. [Local PostgreSQL evidence path](../../server/src/__tests__/cloud-configuration-migration-postgres.test.ts)
|
||||
includes a real fixture worker; it does not establish a hosted replacement.
|
||||
|
||||
Managed adapters: change a visible adapter preference as an instance admin,
|
||||
then use a second application process against the same disposable database to
|
||||
confirm catalog and new-agent selection reflect it. Verify saved agents remain
|
||||
usable. Restart with an operator adapter declaration, confirm its effective
|
||||
list, and reject conflicting toggles. Remove the declaration and confirm saved
|
||||
preferences return. [Database tests](../../server/src/services/adapter-settings-postgres.test.ts)
|
||||
cover local persistence, concurrent writers, audit rollback, and failure responses;
|
||||
[local compatibility tests](../../server/src/services/adapter-settings-local.test.ts)
|
||||
cover the legacy file. No deployed walkthrough is claimed.
|
||||
|
||||
Manual: Change a harmless experimental setting, reload, and confirm the affected route honors it. Back up a disposable instance, inspect the reported file and metadata, and restore using the documented procedure into a second isolated target. Verify a known record after restoration.
|
||||
|
||||
Cloud staging: On a managed `*.staging.paperclip.app` instance, verify experiments
|
||||
@@ -181,5 +152,5 @@ Capability ID: `instance-operations/diagnostics`.
|
||||
|
||||
Scope: cli
|
||||
Storybook: No authored story required for doctor/health command results.
|
||||
Production: Run doctor against an owned data directory; check readiness and nonzero failures. Instance operators can inspect `GET /api/instance/task-drain?upgradeReadiness=1` before a compatible app replacement. Verify that unknown or unsupported executions prevent readiness and that the read does not hold admission; separately prove same-run continuity through an actual upgrade. A listening port alone does not prove readiness; repair requires observing the repaired result.
|
||||
Production: Run doctor against an owned data directory; check readiness and nonzero failures. A listening port alone does not prove readiness; repair requires observing the repaired result.
|
||||
Sources: Source: [doctor.ts](../../cli/src/commands/doctor.ts). Tests: [doctor.test.ts](../../cli/src/__tests__/doctor.test.ts)
|
||||
@@ -112,9 +112,6 @@ to the existing Agent Chat control. Hidden or Cloud-managed controls are not
|
||||
presented as editable. Disabled Chat routes link back to Experimental settings.
|
||||
Enabling the personal workspace never changes the instance capability.
|
||||
|
||||
The Coordinator sidebar has a visible **New task** button above **Chat**. It opens
|
||||
the existing task form and retains the shortcut beside **Tasks**.
|
||||
|
||||
Automated: [preference hook](../../ui/src/hooks/useCoordinatorWorkspaceEnabled.test.tsx),
|
||||
[prerequisite settings card](../../ui/src/components/CoordinatorWorkspaceSetting.test.tsx),
|
||||
[authorization](../../server/src/__tests__/workspace-preferences-routes.test.ts), and
|
||||
@@ -125,15 +122,8 @@ choice. The [Settings card story](../../ui/storybook/stories/navigation-preferen
|
||||
uses the production component with simulated API responses; it does not establish
|
||||
real persistence or permission behavior.
|
||||
|
||||
Local browser verification (2026-10-26, isolated Coordinator worktree): initially
|
||||
off, enabled and persisted across reload, disabled back to classic navigation,
|
||||
then enabled back to Chat / Tasks / Needs You. This used `local_trusted`; signed-in
|
||||
two-person browser isolation remains unverified.
|
||||
|
||||
Coordinator More exposes a pin/unpin button beside every destination. Each flyout
|
||||
row highlights as one surface; its pin appears on row hover or keyboard focus.
|
||||
Opening the flyout focuses its container so Search is not highlighted before
|
||||
interaction. Pinned pages appear beneath More in pinning order and retain the
|
||||
Coordinator More exposes a pin/unpin button beside every destination.
|
||||
Pinned pages appear beneath More in pinning order and retain the
|
||||
existing company-aware routes.
|
||||
Unpin from either the flyout or the pinned row. The list is personal to the current
|
||||
user in this browser, shared across companies; it does not sync across devices.
|
||||
|
||||
@@ -37,18 +37,8 @@ the unprefixed route starts at organization naming on self-hosted instances.
|
||||
Cloud-managed instances reuse their existing company for agent setup.
|
||||
|
||||
First-agent onboarding offers only Claude and Codex, subject to instance adapter
|
||||
availability. GitHub Copilot and other providers remain available through Add
|
||||
agent after onboarding. A saved draft for another provider requires a new choice.
|
||||
Old Copilot drafts discard the retired selection and model, including when both
|
||||
onboarding providers are disabled. The wizard no longer contains Copilot setup
|
||||
UI, connection state, or model discovery; later Add agent retains that support.
|
||||
Changing an unavailable saved provider clears its model. If both first-onboarding
|
||||
providers are unavailable, the wizard explains how to enable one or use New Agent
|
||||
from the Agents page for another provider.
|
||||
Claude and Codex are harness choices, not a forced legacy runtime. Automatic
|
||||
runner selection uses the execution environment's qualified native runner and
|
||||
falls back to legacy on native Windows without changing the onboarding UI.
|
||||
Windows should default to native when its runner platform support is qualified.
|
||||
availability. Other providers remain available through Add agent after onboarding.
|
||||
A saved draft for another provider requires a new choice.
|
||||
|
||||
### `cli-setup`
|
||||
|
||||
@@ -62,19 +52,6 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use
|
||||
|
||||
Automated: [wizard tests](../../ui/src/components/OnboardingWizard.test.tsx) cover mocked wizard behavior; [onboarding browser suite](../../tests/e2e/onboarding.spec.ts) supplies its own test environment. Live model execution is a separate check.
|
||||
|
||||
The [published canary smoke](../../tests/canary-onboarding/canary-onboarding.spec.ts)
|
||||
checks the exact installed version through Connect a model. Submitting the agent
|
||||
name must save one paused setup record with disabled heartbeats and no task or
|
||||
run. The [authenticated release smoke](../../tests/release-smoke/docker-auth-onboarding.spec.ts)
|
||||
checks the same held state, then completes that record through Connect without
|
||||
creating a second agent. Its Docker harness mocks credential verification; live
|
||||
provider authentication remains separate evidence.
|
||||
|
||||
Name-only setup defers the runner field while the provisional adapter remains
|
||||
held in setup. Choosing a provider updates that same setup record with its
|
||||
selected runner. The wizard regression covers a saved native choice followed by
|
||||
OpenAI Subscription selection; it does not prove provider authentication.
|
||||
|
||||
- **Create company and resume.** Start a fresh empty instance and run doctor using
|
||||
the [verification skill](../../.agents/skills/verify-paperclip/SKILL.md). Run
|
||||
`node .agents/skills/verify-paperclip/scripts/onboarding-smoke.mjs --evidence-dir "$VERIFY_EVIDENCE_DIR"`.
|
||||
@@ -159,40 +136,6 @@ parent, and recovery stopped the completion callback before a provider turn.
|
||||
The failed report remains evidence; the revised source still needs live proof.
|
||||
Local cases and automatic selection remain unchanged.
|
||||
|
||||
First-task task creation enforces proposal acceptance at the shared server
|
||||
boundary. Verify that native `create_task` and both REST creation endpoints reject
|
||||
an authenticated onboarding run before its latest proposal has a saved human
|
||||
acceptance, including an explicit standalone parent. Then accept a confirmation
|
||||
or the current plan revision and verify creation succeeds. Opening answers,
|
||||
agent-only acceptance, stale plans and newer pending/rejected proposals must not
|
||||
admit new work. [Admission controls](../../server/src/__tests__/onboarding-first-task-admission.test.ts)
|
||||
exercise native and REST calls against disposable PostgreSQL; live model and
|
||||
Cloud onboarding remain separate evidence.
|
||||
|
||||
For a native proposal, reject root-level `version` or `supersedeOnUserComment`
|
||||
without creating a card. Correct them inside `payload`, preserve the confirmation
|
||||
or checkbox approval kind, and verify one pending card after idempotent replay.
|
||||
An answered question form still cannot authorize the proposed child task.
|
||||
|
||||
After acceptance, reject a new task whose blockers include its onboarding source.
|
||||
The rejected command must leave no task, dependency, wake or creation receipt;
|
||||
a corrected retry must still create the ready child. Preserve valid blockers for
|
||||
other work. Check equivalent UUID spellings and a later child PATCH as well as
|
||||
native dependency edits, including the child's own run with a waiting parent and
|
||||
no first-class dependency yet. Preserve normal API attempt auditing and allow blocker
|
||||
corrections without a new proposal acceptance. The shipped handoff recipe copies the actual approved inputs and
|
||||
constraints into the child, then makes the parent depend on the child. Its
|
||||
schema and persistence controls do not prove that a live model follows it.
|
||||
|
||||
Native completion also requires a saved human proposal decision. An opening
|
||||
answer alone must leave the first task in review. Verify that premature native
|
||||
completion is refused, including a result already saved before finalization.
|
||||
Accepted proposals and acknowledged human rejections can close the first task;
|
||||
rejection still does not authorize new tasks. The
|
||||
[native completion controls](../../server/src/services/native-runtime/paperclip-control-plane-port.test.ts)
|
||||
exercise these boundaries against disposable PostgreSQL. These controls do not
|
||||
identify a historical Cloud failure or establish live onboarding success.
|
||||
|
||||
For accepted file-producing work, verify exactly one self-assigned child with a
|
||||
self-contained description. The onboarding run must yield through the existing
|
||||
dependency/block disposition so the child's own execution can publish its file.
|
||||
|
||||
@@ -44,14 +44,6 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use
|
||||
|
||||
Automated: [projects UI](../../ui/src/pages/Projects.test.tsx) and [project detail](../../ui/src/pages/ProjectDetail.test.tsx) are component tests.
|
||||
|
||||
Automated: the explicit [`project-task-context` deployment journey](../../tests/runner-e2e/product-journeys/project-context-flow.ts)
|
||||
creates a project and a self-assigned task through the production dialogs. It
|
||||
reopens both, verifies the project task list and task properties after reload,
|
||||
and independently checks the saved company, project, prompt, assignment and
|
||||
standard work mode with zero agent runs. [Oracle tests](../../tests/runner-e2e/product-journeys/project-context-evidence.test.ts)
|
||||
reject lost links and mismatched records. This describes coverage; each target
|
||||
still needs its own live pass before daily promotion.
|
||||
|
||||
Manual: Create a project, add a task from its view, and reload. Verify the task belongs to that project, list counts are plausible, and links preserve company scope. Archive only the disposable project and inspect list/task behavior.
|
||||
|
||||
### `repository-settings`
|
||||
|
||||
@@ -79,8 +79,6 @@ Channel-specific forms and identity linking require separate provider evidence.
|
||||
|
||||
## Driving it
|
||||
|
||||
The explicit `plan-revise-accept` and `protected-actions` [Product journeys](../../tests/runner-e2e/PRODUCT-JOURNEYS.md) cover `questions-and-approvals/plan-review` and `questions-and-approvals/tool-review`. They share the classic browser actions and saved-state checks. Cloud qualification remains separate; source registration is not a passing result.
|
||||
|
||||
Preconditions: follow the [baseline](./README.md#before-driving-a-journey).
|
||||
Use separate disposable requests for accept, decline, and revision paths. Record
|
||||
the actor and request revision. Prepare a waiting question through a test agent;
|
||||
@@ -218,8 +216,6 @@ unless its actual provider journey was driven.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Canonical question forms show field validation only after Next/Submit (including the keyboard submit shortcut) is attempted. Invalid answers remain unsent and the form stays on the relevant question; correction clears the field warning. Pagination arrows still browse without validation, drafts remain preserved, and uploads/requests in flight still disable submission.
|
||||
|
||||
- Dismissing a question does not answer it. Dismissing an app review neither
|
||||
grants permission nor resumes the agent. Ordinary comments cannot approve it.
|
||||
- A resolved request and a successful tool execution are separate facts.
|
||||
|
||||
+11
-114
@@ -25,28 +25,9 @@ Agent access: [companion](../agent-access-map/recovery.md).
|
||||
Restart recovery respects live heartbeat preparation before workspace
|
||||
synchronization finishes. PostgreSQL regressions cover unchanged ownership,
|
||||
no duplicate dispatch, and later recovery after preparation leaves the registry.
|
||||
An interrupted run with an audited pending Stop can reattach its exact remote
|
||||
session only for cleanup. It reuses the original held reservation during a
|
||||
budget pause and cannot start another provider turn. Local PostgreSQL
|
||||
[Stop accounting](../../server/src/services/native-runtime/native-stop-accounting.integration.test.ts)
|
||||
and [restart selection](../../server/src/services/native-runtime/native-runner-restart-recovery.integration.test.ts)
|
||||
tests cover cleanup acknowledgement, fenced alternatives, and receipt debt.
|
||||
Cleanup does not stage new attachments, retire another warm owner, or replay
|
||||
pending semantic work. Authenticated Core intake retains that input unanswered.
|
||||
Close still requires confirmed provider exit, durable event drain, and exact
|
||||
runner suspension; the cleanup purpose alone cannot certify termination.
|
||||
Hosted provider settlement remains separate acceptance.
|
||||
An authorized fresh native retry publishes its own session for the next
|
||||
ordinary comment or monitor. The [heartbeat regression](../../server/src/__tests__/native-session-resumption.test.ts)
|
||||
covers fresh admission, saved session selection, and one subsequent resume.
|
||||
Unfinished goals and unverified prior outcomes retain their recovery gates.
|
||||
- `source-action`: `recovery/source-action` — source-scoped recovery actions remain attached to the task;
|
||||
independent repair work may have its own issue and return owner.
|
||||
- `exhaustion`: `recovery/exhaustion` — an exhausted infrastructure attempt offers ordinary Retry.
|
||||
The failed-attempt notice has padding, a tinted background and an error icon;
|
||||
its message and Retry remain readable on narrow screens in both themes. Verify
|
||||
with [the browser layout checks](../../tests/e2e/execution-recovery/failed-attempt-notice.spec.ts)
|
||||
against an owned Storybook server using `RECOVERY_STORYBOOK_URL`.
|
||||
Internal repair stays system-owned; genuine user decisions retain their
|
||||
specific action.
|
||||
- `workspace`: `recovery/workspace` — workspace divergence/export failures show the applicable repair,
|
||||
@@ -58,27 +39,10 @@ Agent access: [companion](../agent-access-map/recovery.md).
|
||||
workspace link when the destination is disabled. Local PostgreSQL and real
|
||||
filesystem regressions cover native and legacy recovery and one-time delivery;
|
||||
hosted provider recovery remains separate acceptance.
|
||||
Daytona directory export can stream its archive when the sandbox cannot store
|
||||
a temporary tar. The transfer remains bounded and validates archive completion
|
||||
and paths before import. The [capacity regression](../../packages/plugins/sandbox-providers/daytona/src/file-sync-capacity.test.ts)
|
||||
exercises a real local PTY and file-size limit. The credential-gated
|
||||
[provider test](../../packages/plugins/sandbox-providers/daytona/src/file-sync-capacity.live.test.ts)
|
||||
covers stop/start, an ENOSPC archive sink, safe-link filtering, and a second
|
||||
export. Neither test proves the original task's continuation or repairs lost
|
||||
provider session state.
|
||||
Native finalization deadline failures also retain the exact prepared source
|
||||
for the same stop-and-save workflow before Retry admits another executor.
|
||||
A blocked native restart records that preservation obligation atomically with
|
||||
its failure. PostgreSQL regressions cover exact source binding, live ownership,
|
||||
rollback, and no replacement run or wake from file preservation.
|
||||
Retry reconstructs missing preservation for historical failures only from an
|
||||
exact prepared source without a live finalization owner.
|
||||
New messages and orphan cleanup can register missing preservation automatically
|
||||
and wake the existing worker. Saved input still waits for verified stop and file
|
||||
persistence, then enters ordinary admission once.
|
||||
A completed explicit Retry also retires its failed, unowned sandbox predecessor's
|
||||
stale retry and registers preservation atomically. Current task state and live or
|
||||
mismatched owners remain protected; workspace switching still waits for cleanup.
|
||||
- `unknown-outcome`: `recovery/unknown-outcome` — uncertain external side effects require inspection and
|
||||
an explicit decision, not automatic replay.
|
||||
- `user-continuation`: `recovery/user-continuation` — saved user messages after a stop are reconsidered once
|
||||
@@ -90,44 +54,13 @@ Agent access: [companion](../agent-access-map/recovery.md).
|
||||
the agent itself restarted or that a failed run succeeded.
|
||||
|
||||
## How to get to it (user POV)
|
||||
For `recovery/reconnect`, interrupt a write response after the server accepts it.
|
||||
Verify that task, document, and decision drafts survive reload and that retrying
|
||||
the saved request does not create a duplicate. After the bounded retry budget
|
||||
ends, use **Resend now** to continue. Check that drafts remain private to their
|
||||
original account and task. See [durable autosave tests](../../ui/src/hooks/useDurableAutosave.test.tsx)
|
||||
and the [disconnect recovery journey](../../tests/e2e/disconnect-write-recovery.spec.ts).
|
||||
|
||||
For `recovery/reconnect`, also interrupt a write response after the server accepts
|
||||
it. Keep a title draft bound to its original task while navigating. Restore a
|
||||
new-task draft with its files selected in another order and require the same
|
||||
creation key and one task. Verify lost document-create and decision responses,
|
||||
including an interrupted verification read. Once the bounded retry budget ends,
|
||||
require a visible **Resend now** action. Use
|
||||
[durable autosave tests](../../ui/src/hooks/useDurableAutosave.test.tsx) and
|
||||
[task creation tests](../../ui/src/components/NewIssueDialog.test.tsx) for the
|
||||
controlled source cases; repeat the real browser journey for acceptance.
|
||||
Switch accounts while an inline edit is open or a channel send waits to retry:
|
||||
the next account must see neither private text nor a retry from the first account.
|
||||
Returning to the original account restores its retained channel request with the
|
||||
same key for explicit retry. Unowned legacy receipts stay held for Activity
|
||||
inspection until a person explicitly discards their browser record; discard does
|
||||
not replay the text or cancel an accepted update. Typing before the first session
|
||||
lookup survives that initial lookup and is backed up under the resolved owner. Component evidence lives in the
|
||||
[inline editor tests](../../ui/src/components/InlineEditor.test.tsx) and
|
||||
[connected-channel tests](../../ui/src/components/chat/ExternallyConnectedTaskBanner.test.tsx);
|
||||
these controlled session changes do not establish hosted authentication acceptance.
|
||||
Also switch accounts during a restored task create and while its files are
|
||||
uploading: later uploads stop, the next account sees a fresh form, and the
|
||||
original request key remains owned by the first account. Reselect colliding
|
||||
text-document filenames in reverse order and verify their original keys and
|
||||
contents. Switch between cached document subjects without copying either draft.
|
||||
A receipt arriving before an in-flight resend must preserve the next message.
|
||||
The startup browser journey in
|
||||
[disconnect recovery](../../tests/e2e/disconnect-write-recovery.spec.ts) holds the
|
||||
first session response while a title save waits, simulates an offline event with
|
||||
API failures while keeping static assets reachable, then verifies the real saved
|
||||
server title after account resolution and reload. The accepted-comment journey
|
||||
then completes and assigns a task before repeating its saved comment request;
|
||||
the original receipt must return once, its activity must appear once, and the task must stay Done. Reusing that
|
||||
key with different text must return a conflict without changing the task. This
|
||||
uses a disposable process agent and makes no provider call. A separate healthy-API
|
||||
startup journey fails the session endpoint with JSON 500 responses, then restores
|
||||
it while an edit waits; the same edit must save and survive reload without a
|
||||
network reconnect or another user action.
|
||||
|
||||
### `source-task`
|
||||
|
||||
@@ -158,10 +91,7 @@ Open the agent's run (`/agents/:agentId/runs/:runId`) from activity or the task'
|
||||
run link. The run page hosts workspace repair 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. Native workspace export failures also offer the
|
||||
read-only **Inspect recovery** control described in the
|
||||
[run diagnostic recipe](activity.md#activity-audit-1). It observes one selected
|
||||
source's recorded identity and does not retry, repair, or authorize execution.
|
||||
stopped-run recovery checks.
|
||||
|
||||
### `operator-retry`
|
||||
|
||||
@@ -253,7 +183,7 @@ Use these checks alongside the entry-point recipes below and the operation recor
|
||||
| --- | --- | --- |
|
||||
| `recovery/diagnosis` | Open the source task and exact run; compare cause, source action, original owner, recovery owner, attempt bounds and next action after reload. | Test an unrelated/private task and a stale run notice. Read-side retirement of a stale action must not create a new attempt, participant, or permission to replay. After workspace recovery, compare task and run instructions; recovered files must not leave instructions to repair a retained sandbox. The stopped run keeps its replay hold until continuation admission. An obsolete exact-session notice retires only after terminal coordinator proof and a separate exact-run workspace hold; no new execution or file cleanup follows. |
|
||||
| `recovery/bounded-continuation` | Use a deterministic recoverable interruption and inspect the original run/session, attempt receipts, saved result and eventual useful output. | Repeat restart/receipt delivery, race Stop or a new owner, and retain unknown external outcomes. Accepted completion/finalization recovery must not start a new provider turn or repeat its side effect. |
|
||||
| `recovery/source-action` | Inspect active and retained actions, follow the repair owner, and resolve one eligible source-bound action with its exact ID. | Retry the settled resolution and reject a stale/foreign action. Recovery ownership alone cannot mutate the source task; inspect source status, audit and wake independently. A running native owner must receive a conflict when resolution would change its own task status; its task tools must remain usable so it can report through semantic completion. Unchanged-status, Board and legacy recovery retain their normal permissions. |
|
||||
| `recovery/source-action` | Inspect active and retained actions, follow the repair owner, and resolve one eligible source-bound action with its exact ID. | Retry the settled resolution and reject a stale/foreign action. Recovery ownership alone cannot mutate the source task; inspect source status, audit and wake independently. |
|
||||
| `recovery/exhaustion` | Exhaust or age a bounded fixture; use the currently offered retry once, then inspect its durable acknowledgement and actual continuation. | Reassign, pause, stop, close, add an unresolved dependency, or impose a budget hold before retry. The old notice must not reopen terminal work or run the wrong owner. |
|
||||
| `recovery/workspace` | Exercise retained-file recovery, export retry, reconstruction, branch repair/reconciliation and exact-owner finalization as distinct authorized operator paths. | Use exact source/action/run/receipt bindings and preserve existing files. Reject stale source, live/uncertain writers, unsafe archives and insufficient authority. Verify actual files and accepted result separately from queued acknowledgement. |
|
||||
| `recovery/unknown-outcome` | Inspect the provider and saved intent before recording a source-specific chat, email or governed-provider outcome. | Use performed, not-performed and unresolved cases. Wrong company/request, stale state and unauthorized resolution must fail. Unknown effects must not replay automatically. An explicit retry must record the operator’s duplicate-risk acceptance and dispatch only the authorized attempt. |
|
||||
@@ -291,15 +221,6 @@ provider restart. For that journey, interrupt a disposable deployment after
|
||||
workspace preparation and before its first executor claim, then confirm one
|
||||
provider turn starts on the original run through the normal admission gates.
|
||||
|
||||
The same suite's `diskless` and `diskless-per-turn` cases exercise three native
|
||||
controller processes with both native projections removed between completed
|
||||
turns. They check history and invocation counts through the real executor and
|
||||
admission snapshot rebinder. The workspace and sandbox remain available, and
|
||||
the processes use the same source revision. Separate Postgres tests cover
|
||||
metadata import, bounded discovery, ownership holds and incomplete-publication
|
||||
retention. These cases do not qualify full webserver disk loss, distinct releases,
|
||||
HTTP traffic continuity, or the live Daytona provider path.
|
||||
|
||||
The [Runner transport regressions](../../packages/paperclip-runner/runner/crates/runner-core/src/durable/transport.rs)
|
||||
exercise a real WebSocket welcome delayed beyond two seconds. Authentication
|
||||
uses the ten-second connection setup budget, clipped by the current lifecycle
|
||||
@@ -315,10 +236,8 @@ historical provider outage or successful hosted task recovery.
|
||||
|
||||
Active remote process supervision distinguishes a failed health read from a
|
||||
confirmed exit. The [executor tests](../../server/src/services/native-runtime/native-session-executor.test.ts)
|
||||
exercise timeout and repeated gateway-failure recovery with a real listening
|
||||
process, unchanged ownership, and rejected identity evidence. Read-only probes
|
||||
use their shared deadline with bounded backoff; fast failures do not exhaust a
|
||||
three-attempt limit. Signal requests remain single-attempt. The Runner restart tests require positive exit
|
||||
exercise timeout recovery with a real listening process, unchanged ownership,
|
||||
and rejected identity evidence. The Runner restart tests require positive exit
|
||||
evidence before replacement. The executor regressions also retire a real child
|
||||
during its metadata read, keep unknown adopted-process ownership held, and reject
|
||||
launch before detachment when Node is unavailable. The diagnostic tests cover
|
||||
@@ -429,32 +348,10 @@ For a source with a retained-file protection marker, exercise recovery through
|
||||
the assembled environment runtime. Its exact preservation owner may reopen the
|
||||
stopped allocation to read saved files; ordinary resume stays blocked. Reject a
|
||||
changed claim, missing stop intent, wrong lease or wrong environment before a
|
||||
provider call. Repeat accepted-native-result copyback for both reusable lease policies. Require
|
||||
the exact accepted result and completion contract; reject a rejected or unselected
|
||||
result, another allocation owner, and an active host writer. Verify no provider
|
||||
turn or wake is created, then finalize the original result once. Reject malformed
|
||||
or oversized Git metadata through native finalization: the run must fail and
|
||||
retain its file-recovery barrier, rather than successfully omitting the export.
|
||||
Exercise both an oversized sender file and an oversized transfer report. Verify
|
||||
one rejected export, no payload read after rejection, and unchanged host files.
|
||||
Reload a large-result run and its activity: the failure code and task recovery
|
||||
notice remain visible, and metadata repair offers no new provider turn. These database
|
||||
and filesystem controls do not qualify a deployed provider.
|
||||
Verify saved and newer local files, one preservation receipt, and
|
||||
provider call. Verify saved and newer local files, one preservation receipt, and
|
||||
no additional agent turn. The PostgreSQL regression covers this boundary; the
|
||||
opt-in provider probe also uses this runtime path with the protection marker.
|
||||
|
||||
Repeat Task Retry with a completed native result whose unfinished export uses
|
||||
the remote-workspace descriptor. Before preservation, require the original run
|
||||
to remain the only task run. After preservation, verify restored file bytes and
|
||||
Git HEAD, commitment of that same result, and an unanswered human review keeping
|
||||
the task In Review. For an action superseded by a newer failure, request exact
|
||||
historical file recovery through the board API: verify a committed snapshot,
|
||||
unchanged newer workspace binding and attention owner, no old-result commitment,
|
||||
and no provider turn. An active current writer or no explicit request keeps the
|
||||
historical source waiting. The PostgreSQL/HTTP regression is in
|
||||
[workspace recovery](../../server/src/services/workspace-recovery.test.ts).
|
||||
|
||||
For a missing managed allocation, verify a fresh Cloud-signed absence observation
|
||||
under the exact physical recovery owner. The existing Retry may then select an
|
||||
independent workspace through normal admission. Verify that the original run
|
||||
|
||||
@@ -29,9 +29,7 @@ Open `/routines`, create one, and inspect `/routines/:routineId` and its edit se
|
||||
### `trigger-history`
|
||||
|
||||
Use the routine's trigger controls and Runs/Recent Runs/Audit links; lists also
|
||||
offer Run now. **View all tasks** opens the Tasks list with **Routine tasks**
|
||||
selected, using `/issues?view=all&originKind=routine_execution&sortField=created&sortDir=desc`. Uncheck the
|
||||
filter to return to other tasks. **History** records configuration versions, not executions.
|
||||
offer Run now. **History** records configuration versions, not executions.
|
||||
|
||||
## Driving it with Playwright and the Paperclip CLI
|
||||
|
||||
@@ -54,15 +52,11 @@ Automated: [trigger wizard](../../ui/src/components/routine-triggers/TriggerWiza
|
||||
|
||||
Manual: Set a near-term disposable schedule or authorized test webhook, verify one eligible execution and its source trigger, then disable it and confirm further invocations stop. Inspect a failed execution without losing its history. Remove the temporary trigger after testing.
|
||||
|
||||
Sentry run-failure alerts can use the bearer-authenticated
|
||||
`/api/routine-triggers/public/:publicId/sentry-run-failures` receiver. It validates
|
||||
the source run against this company's task, admits one repair per failed run,
|
||||
and ignores tasks originating from the repair routine, including children and
|
||||
standalone creation descendants. Private or unreadable sources are ignored rather
|
||||
than copied into company-readable routine history. The routine's instructions
|
||||
should reuse existing repair cases/PRs for the same root cause. Service and HTTP
|
||||
regressions in the routine suites cover recursion, concurrent delivery, and access;
|
||||
these checks do not prove a live Sentry integration is configured.
|
||||
A webhook-triggered routine can receive Sentry run-failure alerts through
|
||||
`/api/routine-triggers/public/:publicId/sentry-run-failures`. Configure bearer
|
||||
authentication, send an alert for an accessible task in the same company, and
|
||||
verify one repair task for the failed run. Failures from the repair routine
|
||||
and its descendants must not trigger another repair. See the [routine API](../../docs/api/routines.md).
|
||||
|
||||
## Gotchas
|
||||
|
||||
@@ -96,5 +90,3 @@ Sources: Source: [RoutineRunVariablesDialog.tsx](../../ui/src/components/Routine
|
||||
### Documentation scope: Routines, cases, and status cards
|
||||
|
||||
All three capabilities have recipes. Trigger/provider/timezone combinations, custom case schemas and summarizer quality need deeper cases.
|
||||
|
||||
The target-independent Product E2E journey `routine-scheduled-run` covers browser creation, an actual scheduled invocation, run-attributed saved output, history after reload, and no new invocation across the next minute boundary after pause. Source: `tests/runner-e2e/product-journeys/routine-schedule-flow.ts`. Registration is not evidence of a passing deployed run.
|
||||
@@ -40,25 +40,6 @@ The agent header has one Run now action. Administrators can enable
|
||||
Capture raw provider traces under the agent configuration’s Debugging section
|
||||
for future runs. The header shows Raw tracing on while that setting is enabled.
|
||||
|
||||
Managed Git launchers let agents save local commits without a GitHub connection
|
||||
or manual author setup. Verify a fresh checkout and a second shell in the same
|
||||
workspace: both commits should use `Paperclip <noreply@paperclip.ing>` when no
|
||||
identity is configured. Repository and command settings override this default;
|
||||
an eligible managed identity still takes precedence. Inspect stored commit
|
||||
metadata and confirm the default did not change repository or host configuration.
|
||||
Repeat with unavailable GitHub access; authenticated operations must still obey
|
||||
the existing credential checks. The [launcher controls](../../packages/adapter-utils/src/github-launcher.test.ts)
|
||||
and [real-shell staging controls](../../packages/adapter-utils/src/github-launcher-environment.test.ts)
|
||||
cover this local behavior, separately from live cloud execution and GitHub writes.
|
||||
|
||||
Native Runner agents wait for task-bound work. A generic heartbeat interval does
|
||||
not create a taskless run or put an otherwise ready agent into an error state.
|
||||
Assigned tasks, task monitors, routines and task-bound timer wakes keep their
|
||||
existing admission paths; Legacy adapter intervals remain supported. The
|
||||
[scheduler](../../server/src/services/heartbeat/scheduling.test.ts) and
|
||||
[queue](../../server/src/services/heartbeat/queue.test.ts) regressions exercise
|
||||
this boundary with PostgreSQL and synthetic execution, separately from live task acceptance.
|
||||
|
||||
For latency diagnosis with an operator OTLP endpoint, search the hashed run ID
|
||||
without restricting the root span name. Compare workspace preparation with its
|
||||
`workspace_<step>` intervals. Measure controller readiness separately through
|
||||
@@ -93,84 +74,6 @@ mutations. Qualify a useful model task separately from saving the account.
|
||||
|
||||
### `session`
|
||||
|
||||
Recover an in-flight remote runner after controller restart, then let it finish
|
||||
with slow instruction collection. Send two follow-ups without resetting its
|
||||
session. Verify that completion does not detach the retained runner and that
|
||||
provider history survives with one turn per wake. Preparation must retain its
|
||||
lease until execution owns renewal; a genuine ownership loss must still detach.
|
||||
The [remote continuity regression](../../doc/testing-native-remote-continuity.md)
|
||||
uses a real Linux runner and deterministic provider. Live provider acceptance is
|
||||
a separate check.
|
||||
|
||||
Repeat with a full prior-run controller projection that predates its committed
|
||||
database checkpoint under the same run ID. Admission must refresh that projection
|
||||
before reuse. A pending canonical command must still hold execution; current-run
|
||||
state and a retained warm owner must keep their existing authority.
|
||||
|
||||
In a fresh sandbox workspace, fetch a different published branch with depth one,
|
||||
then save a local result and finish. Verify export imports the shallow history,
|
||||
retains host-only edits, and completes finalization without another provider turn.
|
||||
Repeat when the host already has that branch history; its ancestry must remain
|
||||
available. The filesystem sandbox regression covers transfer and merge behavior,
|
||||
not live provider acceptance.
|
||||
|
||||
For a plugin computer, complete a task, let its warm session suspend, then send
|
||||
two follow-ups within the next warm window. Verify the first resumes the saved
|
||||
session and the second keeps the same provider history without an identity
|
||||
mismatch. After a fresh recovery into a repository-free directory, send another
|
||||
ordinary follow-up. Verify it retains that directory without Core Git worktree
|
||||
preparation. Explicit repository strategies and changed provider owners must
|
||||
remain denied. Executor and workspace-preparation regressions cover control
|
||||
behavior; they do not establish live provider acceptance.
|
||||
|
||||
For a remote OpenCode agent configured with `per_turn`, complete a task, then
|
||||
send two follow-ups without resetting its session. Verify that each continuation
|
||||
restores its external controller checkpoint, retains provider context and saved
|
||||
files, and finishes with no stranded task lock. A missing checkpoint, an active
|
||||
prior owner or a mismatched session must still stop admission. The
|
||||
rejected active-owner attempt must not prevent a later continuation from reading
|
||||
the owner's newer completed checkpoint. The
|
||||
[executor controls](../../server/src/services/native-runtime/native-session-executor.test.ts)
|
||||
cover checkpoint restoration and its guards; real-provider acceptance remains
|
||||
separate evidence.
|
||||
|
||||
For native OpenCode, hold an assigned tool result for more than 30 seconds.
|
||||
Verify that the provider receives the saved result once and the next run can
|
||||
attach with no pending tool call. Stop and bridge teardown must still end an
|
||||
unanswered wait without claiming the action failed or repeating it. The
|
||||
[native proxy regression](../../packages/paperclip-runner/src/live/runnerd-opencode-streaming-tools.test.ts)
|
||||
uses the real Rust Runner and proxy with a deterministic provider; live provider
|
||||
and deployed sandbox acceptance remain separate evidence.
|
||||
|
||||
After a completed warm turn, change an agent setting that invalidates its
|
||||
instruction copy, then send a follow-up. Verify the old runner suspends during
|
||||
preparation, saved files remain available, and the follow-up completes once.
|
||||
Repeat with an expired or foreign preparation owner and verify that execution
|
||||
stays held. The checkpoint integration regression covers the ownership boundary;
|
||||
a real provider run remains separate acceptance evidence.
|
||||
|
||||
For a repository project that inherits storage-plugin defaults, run a task and
|
||||
send two follow-ups. Start with unset task workspace settings, then repeat with
|
||||
an explicit isolated mode or strategy. Binding must save `reuse_existing` and
|
||||
the resolved mode without changing the effective policy,
|
||||
session fingerprint, and workspace identity. An actual project-policy change
|
||||
must still reset the session and preserve the stored workspace owner. The
|
||||
[session admission regression](../../server/src/__tests__/heartbeat-session-preparation.test.ts)
|
||||
checks this with PostgreSQL and synthetic provider execution; it is not live
|
||||
warm-process or latency evidence.
|
||||
|
||||
After an isolated remote Retry, send a follow-up with unchanged workspace policy.
|
||||
Verify the same workspace remains bound and no strategy-replacement operation is
|
||||
recorded. Change the strategy or base ref and confirm that the normal replacement
|
||||
guard still applies. The
|
||||
[remote preparation regression](../../server/src/services/heartbeat/workspace-preparation.test.ts)
|
||||
checks persisted configuration across both admissions; it does not prove a live
|
||||
provider conversation resumed.
|
||||
|
||||
For a workspace carrying an older temporary fingerprint, verify that ordinary
|
||||
reuse retains the strategy warning. Use the normal fresh recovery flow after
|
||||
preserving its work, then repeat the unchanged follow-up check on the new workspace.
|
||||
|
||||
For `runs-adapters/session`, complete a task in a disposable warm sandbox and
|
||||
retain its saved workspace file. Let the warm session close normally and verify
|
||||
that the retained lease has a complete, lease-bound harness backup before
|
||||
@@ -182,11 +85,6 @@ reads the retained file and appends one new line. Verify a replacement sandbox,
|
||||
a new provider session, the exact file contents, successful finalization and no
|
||||
stranded task lock. Send another follow-up and verify ordinary session reuse.
|
||||
|
||||
With external controller checkpoints enabled, also admit a fresh session on a
|
||||
reused sandbox lease. Verify startup from canonical controller evidence and
|
||||
reject a marker without a registered controller, changed identity or prior turn
|
||||
activity. An existing remote session directory must retain its recovery gate.
|
||||
|
||||
Repeat without resetting the session: its replacement must restore verified
|
||||
history or remain blocked. Missing backup state must not silently start an
|
||||
existing session again. The [executor controls](../../server/src/services/native-runtime/native-session-executor.test.ts)
|
||||
@@ -194,15 +92,9 @@ cover the bootstrap identity, activity and atomic directory claim; those
|
||||
controls do not establish live provider acceptance.
|
||||
|
||||
### `adapter-setup`
|
||||
Cloud-managed instances load adapters from the release image. Installing,
|
||||
removing, or overriding adapters remains platform-managed.
|
||||
|
||||
Cloud-managed instances load adapters from the release image. Saved external
|
||||
registrations cannot replace built-ins or supply UI parser code. Install,
|
||||
reinstall, reload, remove, and override operations remain platform-managed.
|
||||
The [fixture loader controls](../../server/src/adapters/cloud-external-adapters.test.ts)
|
||||
exercise real packages, import side effects, both managed-instance signals and
|
||||
self-hosted compatibility. The [route authorization controls](../../server/src/__tests__/adapter-routes-authz.test.ts)
|
||||
check managed denials before package or registration access. These are local
|
||||
controls, not live Cloud provider qualification.
|
||||
|
||||
Automated: [adapter validation routes](../../server/src/__tests__/agent-adapter-validation-routes.test.ts) and [model refresh](../../server/src/__tests__/adapter-model-refresh-routes.test.ts) cover server behavior.
|
||||
|
||||
@@ -219,16 +111,6 @@ Cloud onboarding must not offer shell commands the customer cannot run.
|
||||
|
||||
Manual: Select the intended adapter and account, refresh model choices, and run its environment test. Save, reload, then execute a small task. Repeat with a deliberately unavailable account and verify the failure remains visible.
|
||||
|
||||
The explicit-only [Antigravity agent journey](../../tests/runner-e2e/ANTIGRAVITY-AGENT-JOURNEY.md)
|
||||
checks a saved personal subscription, prompt-free native Test and exact low model,
|
||||
then independently correlates two actual downloaded outputs, accepted/committed
|
||||
Done lineage, native conversation continuity and owned runtime retirement. Its
|
||||
first settlement is captured before follow-up reopening; a later coordinator
|
||||
assessment cannot erase that historical Done decision. A failed finish must not
|
||||
mark prior completed file operations failed. The current local macOS ARM64
|
||||
candidate scope leaves fresh authorization, remote targets and release
|
||||
qualification unproven.
|
||||
|
||||
For Legacy Codex, assign a service secret such as `SLACK_BOT_TOKEN` through agent
|
||||
configuration and run a task that checks its presence without printing its value.
|
||||
Check both ACP and CLI execution. Remove the binding and repeat on the next run.
|
||||
@@ -296,13 +178,7 @@ cover ordering, failure drain and credential projection; they do not qualify a
|
||||
live response-time target.
|
||||
For native OpenCode with assigned connections, inspect the provider tool surface
|
||||
on both local and sandbox execution. It should contain bounded assigned-tool
|
||||
search/call schemas. Confirm the search description states the 1–20 page limit
|
||||
and default of 5. Follow `nextOffset` to inspect later pages.
|
||||
Repeat discovery with empty and whitespace-only `schemaTool` values, including
|
||||
`schemaOffset: 0`, and confirm it still returns searchable tools. An unknown
|
||||
schema reference or a positive schema offset without a reference must explain
|
||||
how to correct the call.
|
||||
Discover an allowed tool, call its returned alias, revoke
|
||||
search/call schemas. Discover an allowed tool, call its returned alias, revoke
|
||||
its grant, and confirm discovery and execution enforce that revocation. Repeat
|
||||
in planning/ask mode with a write tool and confirm denial. The controller must
|
||||
retain the assigned gateway URL and token. An older direct-catalog OpenCode
|
||||
@@ -344,14 +220,6 @@ a separate acceptance requirement.
|
||||
|
||||
Automated: [live run routes](../../server/src/__tests__/agent-live-run-routes.test.ts) and [run event sequencing](../../server/src/__tests__/heartbeat-run-event-sequencing.test.ts) cover run data contracts.
|
||||
|
||||
For `runs-adapters/runs`, verify a provider rejection during startup and during a
|
||||
turn. The task interruption and run detail must show the same sanitized provider
|
||||
explanation after reload. Unknown provider categories keep their message. A newer
|
||||
attempt or a completed task hides the stale task notice, while historical run
|
||||
details retain it. Check that existing retry and access gates remain effective.
|
||||
The transport restart regression and PostgreSQL finalization integration cover
|
||||
the persisted cause; component tests cover plain-text rendering and read-only use.
|
||||
|
||||
Manual: Start a disposable task, open its running transcript, and follow it to a terminal outcome. Reload and compare task/run IDs, status, output, and cost. Verify a failed run remains distinguishable from a completed run with useful output.
|
||||
|
||||
For Legacy OpenCode on a disposable Linux sandbox, run a Bash tool that reads
|
||||
|
||||
@@ -26,12 +26,6 @@ Agent access: [companion](../agent-access-map/secrets.md).
|
||||
|
||||
Open company Settings → Secrets and the company/personal secret views.
|
||||
|
||||
An agent's **Secrets** page also shows its environment variables, including
|
||||
masked inline values, company secret references, and user secret references.
|
||||
Environment bindings remain available from **Harness / Runtime** as well.
|
||||
Save an added variable and reload to confirm that the existing masked bindings
|
||||
and their secret references remain present.
|
||||
|
||||
### `proposal-import`
|
||||
|
||||
Use the Proposals tab or Import from vault where available.
|
||||
|
||||
@@ -45,8 +45,6 @@ Use skill policy/agent selection in the library or an agent’s Skills tab.
|
||||
|
||||
## Driving it with Playwright and the Paperclip CLI
|
||||
|
||||
The explicit `create-skill-studio` [Product journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md) covers `skills/authoring`: native creation of an owned company skill, its task activity card, a Studio edit, reload, and task-card readback. It does not establish policy, source-update, or Studio-test coverage. A deployed target requires its own live result.
|
||||
|
||||
Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a harmless skill fixture and test agent with skill support. Record whether the source is local, bundled, project, or remote.
|
||||
|
||||
### `library-sources`
|
||||
@@ -61,20 +59,6 @@ Automated: [Studio](../../ui/src/pages/SkillStudio.test.tsx) covers UI behavior;
|
||||
|
||||
Manual: Create or fork a disposable skill, edit instructions, save, and reload. Run a bounded test, respond to any question, and inspect the output. Verify the saved version matches what was tested and failed saves retain the draft.
|
||||
|
||||
For managed skills, open the same file in two Studio sessions. Save through one,
|
||||
then save the other's stale draft. It must receive a conflict, retain its text,
|
||||
and offer **Load latest saved file** with discard confirmation. File reads and
|
||||
mutation results identify the committed version. Managed content has no server
|
||||
source-directory repair flow. The [domain regression](../../server/src/__tests__/managed-skill-content.test.ts)
|
||||
and [process qualification](../../server/src/__tests__/ephemeral-skills-process.test.ts)
|
||||
cover fresh-home recovery; remote Runner staging remains a separate live proof.
|
||||
|
||||
Version history lists file metadata without downloading archives. Opening a diff
|
||||
fetches only its selected versions; restoring fetches the chosen version. The
|
||||
[library UI regression](../../ui/src/pages/CompanySkills.test.tsx) checks deferred
|
||||
loads; the [package regression](../../server/src/__tests__/skill-package-store.test.ts)
|
||||
checks that slow archive verification cannot hold up a warm agent preparation.
|
||||
|
||||
### `agent-enablement`
|
||||
|
||||
Automated: [policy service](../../server/src/__tests__/company-skill-policy-service.test.ts) and [agent skills state](../../ui/src/pages/agent-skills/AgentSkillsTab.test.ts) cover policy/state contracts.
|
||||
@@ -103,14 +87,6 @@ version pins. The [concurrency regression](../../server/src/__tests__/company-sk
|
||||
checks shared work and separate actor access; the cache tests check that cleanup
|
||||
cannot remove a snapshot before the run stores its pins.
|
||||
|
||||
The [package storage regression](../../server/src/__tests__/skill-package-store.test.ts)
|
||||
covers external snapshots, automatic legacy conversion and exact-commit recovery. A warm selected-repository
|
||||
check must perform no object reads or repository-content SQL. Source/library
|
||||
reconciliation remains available for discovery and mutable sources. The native context
|
||||
regression checks that warm asset packaging reuses verified files, repairs missing/corrupt copies,
|
||||
and notices source edits. Verify both writer-switch states during rollout; see
|
||||
[package storage](../../doc/skill-package-storage.md).
|
||||
|
||||
## Gotchas
|
||||
|
||||
- The release picker requires `enableBetaSkills`. Do not invent an Instructions
|
||||
@@ -166,12 +142,6 @@ Capability ID: `skills/testing`.
|
||||
Scope: ui
|
||||
Storybook: Studio test inputs/configuration, running, question/approval, result and failed test states.
|
||||
Production: Run bounded test of actual saved version with correct selected account/environment; inspect persisted test detail and eligible interaction response.
|
||||
Remote Runner selection accepts the Studio test work mode and preserves its
|
||||
restricted scope; live qualification must cover the saved version delivered to
|
||||
the selected Computer, including a skill with no permanent agent assignment.
|
||||
The [execution configuration regression](../../server/src/__tests__/heartbeat-execution-configuration.test.ts)
|
||||
checks that Studio's historical version replaces ordinary assignments without
|
||||
changing the agent's configuration. Use an isolated Runner home for this journey.
|
||||
Sources: Source: [SkillStudio.tsx](../../ui/src/pages/SkillStudio.tsx), [companySkills.ts](../../ui/src/api/companySkills.ts). Tests: [SkillStudio.test.tsx](../../ui/src/pages/SkillStudio.test.tsx), [company-skill-test-runs-service.test.ts](../../server/src/__tests__/company-skill-test-runs-service.test.ts)
|
||||
|
||||
### Documentation scope: Skills, Skill Studio, and teams
|
||||
|
||||
@@ -35,7 +35,7 @@ Agent access: [companion](../agent-access-map/steering.md).
|
||||
|
||||
Open an assigned task (`/issues/:issueId`). Start work, then send follow-ups while
|
||||
the agent runs. Use the queued-message controls to edit, reorder, discard,
|
||||
steer, or interrupt when offered. After Stop, choose **Send** on a saved queue to explicitly continue it without recreating the messages or attachments. Native steering still requires an active turn; Send after Stop is a separate user decision. Use the composer stop/pause control separately.
|
||||
steer, or interrupt when offered. Use the composer stop/pause control separately.
|
||||
Both task presentations need attention when changing their shared behavior.
|
||||
|
||||
### `agent-chat`
|
||||
@@ -58,15 +58,6 @@ inspect the resulting task and run in Paperclip.
|
||||
|
||||
## Driving it
|
||||
|
||||
The explicit `stop-redirect` [Product journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md) covers `steering/stop-and-pause` only for Stop and one new direction. It requires active work, native cancellation acknowledgement, resource cleanup, and completion without later original-turn activity. It does not qualify pause, interrupt, or all queued-message behavior. Source registration is not a live Cloud pass.
|
||||
|
||||
The explicit `followup-while-running` [Product journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md#active-follow-up)
|
||||
covers `steering/queue`: one follow-up is saved while a bound native command is
|
||||
active, its late requirement appears in one attributed final reply, the queue
|
||||
empties, and the result survives reload. One steered turn or one normal successor
|
||||
is allowed. Unit calibration and source registration are not live acceptance.
|
||||
|
||||
|
||||
Preconditions: follow the [baseline](./README.md#before-driving-a-journey).
|
||||
Use an agent that stays busy long enough to inspect the queue. Record the adapter,
|
||||
native/legacy mode, and advertised steering capability. Test supported and
|
||||
@@ -86,10 +77,6 @@ consumed message whose send response and queue snapshot arrive late. A started
|
||||
run's input receipt removes that message from pending, while a separate unsent
|
||||
message stays queued. Admission to a run that has not started is not delivery.
|
||||
A later retry of the same message remains visible in its new authoritative queue.
|
||||
A queued turn's own starting input stays in history before execution, including
|
||||
board messages that reopen a task. Later inputs keep their queue controls and
|
||||
full canonical order. A maintenance hold displays its current admission wait;
|
||||
drain release and expiry prompt normal admission without a manual retry.
|
||||
Receipts retain the primary wake and coalesced source queue IDs. They clear a late
|
||||
snapshot even when its target names the preceding run or is null.
|
||||
|
||||
|
||||
@@ -25,11 +25,6 @@ Agent access: [companion](../agent-access-map/task-coordination.md).
|
||||
|
||||
Open the task’s parent/child and dependency links in task detail.
|
||||
|
||||
The task feed shows a linked card when an agent creates a direct subtask or a
|
||||
follow-up task from that task. The card stays at its creation time beside
|
||||
documents and artifacts. It shows the current task title, number, and status.
|
||||
The Tasks tab retains the complete relationship list.
|
||||
|
||||
### `review-and-controls`
|
||||
|
||||
Inspect the task’s execution policy and available review, pause, resume, or stop controls.
|
||||
@@ -46,11 +41,6 @@ creates a hold; it does not change task statuses to a paused status.
|
||||
|
||||
Automated: [dependency wakeups](../../server/src/__tests__/issue-dependency-wakeups-routes.test.ts) checks server behavior; visual relationship navigation remains a manual check.
|
||||
|
||||
The [created task card stories](../../ui/storybook/stories/task-coordination/task-created-inline.stories.tsx)
|
||||
render the production feed with fixture task reads. The
|
||||
[task feed tests](../../ui/src/components/TaskChatThread.task-creation-order.test.tsx)
|
||||
check creation order, current status, links, and duplicate suppression.
|
||||
|
||||
Manual: Block one task on another, finish the prerequisite, and observe the dependent task’s eligible continuation. Follow parent/child links back to the source request. Verify no duplicate run or false parent completion occurs.
|
||||
|
||||
### `review-and-controls`
|
||||
@@ -69,19 +59,10 @@ their execution, and uncertain prior executions must be reconciled before waking
|
||||
### Plugin task panels
|
||||
|
||||
An installed plugin can offer an agent detail tab in the task side panel through
|
||||
its optional `taskSidePanel` declaration. The launcher offers that view for the
|
||||
running agent, or the task's assigned agent when idle. Manual selection mounts
|
||||
the same authorized viewer used on the agent page and needs no activity event.
|
||||
The view remains selectable after the run ends.
|
||||
|
||||
A declared activation pair controls automatic opening. The runtime captures
|
||||
Runner context before use and records `runtime.activity.recorded` after success.
|
||||
Core maps that namespace/activity key to the declaration and restores it from
|
||||
the run log on reload or reconnect. After matching activity, readiness gets
|
||||
three bounded attempts with no periodic availability poll. A ready view opens
|
||||
the pane and selects its tab once per run, respecting dismissal during that run.
|
||||
Declarations without a mapping support manual selection. Plugins own viewer
|
||||
content, readiness, and authorization. Missing or disabled plugins add no view.
|
||||
its optional `taskSidePanel` declaration. Open the view from the task side-panel
|
||||
launcher for the running agent, or the assigned agent when idle. The plugin owns
|
||||
its label, viewer, and access checks. Missing or disabled plugins add no view.
|
||||
A closed panel can be reopened from the launcher.
|
||||
|
||||
Implementation: [panel discovery](../../ui/src/hooks/useTaskPluginPanels.ts) and
|
||||
[task panel](../../ui/src/components/task-side-panel/TaskSidePanel.tsx).
|
||||
|
||||
@@ -20,9 +20,6 @@ Agent access: [companion](../agent-access-map/tasks.md).
|
||||
|
||||
- `discussion`: `tasks/discussion` — persist comments, references, and files on the task.
|
||||
- `completion`: `tasks/completion` — distinguish backlog, active work, review, blocked, done, and cancelled outcomes.
|
||||
A board user closing an active native task must stop its run before the task
|
||||
releases execution ownership, including providers without session goals.
|
||||
Verify Done and Cancelled, an unconfirmed stop, and ordinary agent completion.
|
||||
- `privacy`: `tasks/privacy` — create private tasks, share or revoke access, and inspect parent/project inheritance before changing visibility.
|
||||
|
||||
The [Product task-properties journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md)
|
||||
@@ -30,12 +27,6 @@ checks only assignment to the signed-in user and persistence after reload. Its
|
||||
source is reusable across self-hosted and Cloud; Cloud live qualification is
|
||||
separate. It does not cover other property operations or agent authorization.
|
||||
|
||||
The [Product task-search-filter journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md)
|
||||
checks `tasks/organize` with owned matching and nonmatching controls, exact task
|
||||
identities, saved task content, and search/status persistence after reload and
|
||||
detail/back navigation. It is model-free and reusable across deployment targets.
|
||||
Live Cloud qualification is separate from the journey's assertion unit tests.
|
||||
|
||||
## How to get to it (user POV)
|
||||
|
||||
Cold collection loads use a lightweight index and batched hierarchy context,
|
||||
@@ -44,56 +35,18 @@ visible-row details independently when verifying `tasks/organize`: row heights,
|
||||
title bounds, and the first-row origin should remain stable. Test nested expansion,
|
||||
scrolling to more rows, and detail/back navigation; a collection projection must
|
||||
never suppress the full task instruction fetch.
|
||||
Coordinator Tasks uses the same index and visible-row enrichment. Needs attention
|
||||
resolves pending task IDs in batches of at most 100; it does not fetch enriched
|
||||
task detail for every decision. Search and participant filters stay on the server.
|
||||
Cold Coordinator detail must stay compact when Classic settings arrive before
|
||||
the personal workspace preference. Verify explicit history expansion afterward.
|
||||
|
||||
### `new-task`
|
||||
|
||||
Use New task from the global launcher, task list, or project task view.
|
||||
Images selected, pasted, or dropped into either the new-task or thread composer
|
||||
appear as equal-size rounded thumbnails above the text. Check mixed image/file
|
||||
selections, removal, thread upload failure/retry, and restored thread drafts.
|
||||
New-task files persist in account- and company-scoped browser storage across
|
||||
reloads and are cleared after creation. Verify that restored image bytes reach
|
||||
the task and that older inline-image drafts keep the rich editor.
|
||||
The Storybook new-task and add-menu suites have desktop and mobile image examples;
|
||||
their upload and submit boundaries are fixtures.
|
||||
|
||||
### `task-list`
|
||||
|
||||
Scheduled ordinary monitor waits display **Monitoring** with a blue clock in
|
||||
current task indicators, groups, board columns, and filters. Compare Monitoring
|
||||
with In Progress, then start the check and verify the status returns to its
|
||||
execution presentation. Retained monitors must not override blocked/review or
|
||||
terminal states. Inspect due/overdue copy separately; no runner is implied.
|
||||
|
||||
Open `/issues` or a project’s Issues view; legacy `/tasks` links redirect.
|
||||
Filters → **Routine tasks** selects tasks created by routine runs. The
|
||||
`/issues?view=all&originKind=routine_execution&sortField=created&sortDir=desc` link opens that selection with newest-created tasks first. Sort controls update
|
||||
`sortField` and `sortDir` in the URL. Reloads and task return links keep that order.
|
||||
Shared sort links also retain their order when opened in another task interface.
|
||||
|
||||
### `task-detail`
|
||||
|
||||
During a cold open, task data prepares behind the shell loading view until the
|
||||
personal presentation preference resolves. The temporary shell stays hidden.
|
||||
The matching chat loading frame then owns the same viewport and
|
||||
composer geometry as the resolved conversation. The real title and monitor
|
||||
banner stay concealed until the initial reading position is prepared. The
|
||||
[rich loading journey](../../tests/perf/issue-detail/loading-layout.spec.ts)
|
||||
checks direct and list-based entry, delayed fonts and preferences, and desktop/mobile geometry
|
||||
with a long saved thread, cards, a monitor, and a pending confirmation. This
|
||||
synthetic local coverage does not establish a deployed staging pass. The normal
|
||||
[browser CI journey](../../tests/e2e/task-loading-frame.spec.ts) also covers the
|
||||
loading contract, Classic preference loading and typography, stable mobile chrome,
|
||||
and a bounded wait for stalled fonts.
|
||||
|
||||
Open `/issues/:issueId` from a row, mention, or direct link. Cold opens show the instruction, recent exchange and saved cards together. Completed runs with saved replies defer their transcripts until the reader opens history. Live runs, failures, yielded runs and runs without a saved reply still hydrate; an already shown transcript stays available after completion. No URL fragment expands history; older-comment anchors fetch only their target, and document anchors open the pane. **More messages** appears only when earlier comments or runs are omitted and loads that history. Fresh tasks with no omitted history have no disclosure. A single run with deferred output or a truncated legacy log offers **More run output** instead. **More task actions → Show task activity** loads full activity even for a single native run; incoming messages remain visible while the task stays open.
|
||||
|
||||
For an ordinary native task, deferred workspace finalization must preserve the final reply for both completed work and work awaiting review. Reload must show that saved reply once. The pending review stays pending; publishing the reply does not approve it or start another run. The [database recovery suite](../../server/src/services/native-runtime/agent-chat-response-recovery.test.ts) covers deferred review publication, exact final-message selection and review preservation. Live acceptance is recorded in the pull request.
|
||||
Open `/issues/:issueId` from a row, mention, or direct link. Cold opens show the instruction, recent exchange and saved cards together. **More messages** appears only when earlier comments or runs are omitted and loads that history. Fresh tasks with no omitted history have no disclosure. A run with deferred output or a truncated legacy log offers **More run output**. **More task actions → Show task activity** loads full activity even for a single native run; incoming messages remain visible while the task stays open.
|
||||
|
||||
### `task-sharing`
|
||||
|
||||
@@ -135,8 +88,6 @@ Use a human/unassigned task to verify persistence without invoking a model.
|
||||
|
||||
Automated: [task-list helpers](../../ui/src/pages/Issues.test.tsx) cover search URLs, pagination, deduplication, and presentation constants. The suite does not render the page or exercise filtering, grouping, opening a task, and returning; those interactions still need a running-browser check.
|
||||
|
||||
Task and inbox rows omit the system interruption labels **Thinking**, **Trying again soon**, and **Retry available**. [Shared row tests](../../ui/src/components/IssueRow.test.tsx) cover working, scheduled-retry, and failed interruptions in both row presentations, including suppression of replacement recovery chips. Task status and other relevant badges remain visible; retry controls remain inside the task conversation.
|
||||
|
||||
Manual: Seed human-created, agent-created, scheduled routine, human-initiated chat-channel, and creator-less tasks. Confirm automation is hidden by default, **Show agent-created tasks** reveals it, reload preserves the choice, and Clear filters hides it again. Verify list and board search with automation newer than the human results, and expand contextual ancestors/subtasks without promoting unrelated automated roots. Repeat in project task lists. Agent profiles and task-detail subtasks retain complete history.
|
||||
|
||||
Manual: Filter by status and assignee, change grouping/sort, open a task, and return. Verify the correct records and selected view survive navigation and reload. Include an empty result and a failed request.
|
||||
@@ -147,8 +98,6 @@ Manual: Open a long task with slow historical requests. Read the instruction and
|
||||
|
||||
Automated: [cold-open reads](../../server/src/__tests__/task-cold-open.test.ts) cover bounded reads, event filtering and company denial. [Task detail](../../ui/src/pages/IssueDetail.test.tsx) covers component behavior, while [issue service](../../server/src/__tests__/issues-service.test.ts) covers server contracts.
|
||||
|
||||
The opt-in [saved-reply browser case](../../tests/perf/issue-detail/saved-reply-startup.spec.ts) uses 200 completed native runs and long saved replies in a disposable PostgreSQL instance. It holds transcript reads, checks desktop/mobile first-reveal geometry, then opens history while retaining the editor and draft. See its [setup](../../tests/perf/issue-detail/README.md).
|
||||
|
||||
Failure markers have no dashed divider rules. An adjacent run error and
|
||||
no-live-execution-path notice show only the last error, with its details and
|
||||
retry action, including a permitted legacy run retry carried onto a later
|
||||
@@ -187,13 +136,6 @@ schema feedback supports a corrected call before a wait is claimed.
|
||||
For a due monitor held by execution recovery, confirm that the schedule remains
|
||||
and task activity explains the deferral. Repeated checks must not replay the held
|
||||
work. Resolve the hold through its existing recovery action, then verify one wake.
|
||||
On a blocked task with a retained monitor, verify that automatic checks show as
|
||||
paused. Check now requests one check through normal admission without changing
|
||||
the task status. Confirm that an unresolved dependency or recovery hold prevents
|
||||
dispatch and does not produce a success message. Backlog and todo tasks must not
|
||||
offer Check now. Blocked provider-quota recovery must offer no manual check and
|
||||
retain its schedule until the task resumes. Agents and automatic ticks cannot
|
||||
check a blocked task.
|
||||
Hold native finalization after the provider has stopped, and verify that both
|
||||
scheduled and manual checks retain the due monitor. After settlement, verify one
|
||||
wake. If its timeout passes during workspace recovery, verify settlement followed
|
||||
|
||||
@@ -43,15 +43,6 @@ Live staging acceptance remains separate from these regression tests.
|
||||
|
||||
Use the task’s workspace card or Files panel and follow its workspace link.
|
||||
|
||||
Native artifact-copy verification: in an admitted standard-mode task, save a
|
||||
synthetic API response and call `download_artifact` with its saved identity and a
|
||||
new workspace-relative filename. Independently inspect the file's complete byte
|
||||
count and SHA-256 through the admitted filesystem. Retry the identical request;
|
||||
reject a conflicting destination, symlink, revoked authority and foreign artifact.
|
||||
The transfer does not change the content's untrusted status. See
|
||||
[API tools](../../doc/runner-api-tools.md#verified-artifact-installation) for support
|
||||
and limits. Provider-free regression evidence is not live remote qualification.
|
||||
|
||||
### `workspace-management`
|
||||
|
||||
Open `/workspaces`, a project workspace, or `/execution-workspaces/:workspaceId` and its Services/Configuration/Runtime logs views.
|
||||
@@ -83,46 +74,9 @@ or original Git remote. Read-only cross-project referenced folders must fail
|
||||
admission. Separate workspaces may run concurrently; shared concurrent writers
|
||||
must be rejected.
|
||||
|
||||
Repeat remote capture with enough free space for the archive and normalized Git
|
||||
metadata, but not another working-tree copy. Verify saved files and Git state
|
||||
after restore. A concurrent file change must fail capture without publishing a
|
||||
receipt or retaining a partial archive. The
|
||||
[portable archive suite](../../server/src/services/remote-workspace-snapshot-archive.test.ts)
|
||||
checks the space allowance and concurrent-change boundary; its filesystem quota
|
||||
is controlled test input, not a live sandbox qualification.
|
||||
|
||||
For Daytona, also fail the guarded file-download copy after a workspace archive
|
||||
exists. Verify export preserves the complete archive, removes partial copies,
|
||||
and succeeds again after reconnect. A failed or oversized stream must preserve
|
||||
newer host files. The [capacity suite](../../packages/plugins/sandbox-providers/daytona/src/file-sync-capacity.test.ts)
|
||||
uses real local copies and terminals; the adjacent opt-in live suite checks
|
||||
disposable Daytona allocations without filling their disks.
|
||||
|
||||
Create a child that inherits a saved isolated workspace or operator branch.
|
||||
Verify it continues the same files after the prior writer saves, including on a
|
||||
new allocation. Two bound children must not acquire concurrent writer authority.
|
||||
Start the child while its parent is still writing. Verify it waits with one
|
||||
scheduled retry and retains its workspace binding without acquiring an allocation.
|
||||
Stop the waiting task and verify that the retry cannot execute. A stale writer
|
||||
or a stopped writer with unfinished saves must remain fenced.
|
||||
Reassign the child during preparation before reservation reports contention;
|
||||
retry promotion must cancel the former assignee's run without starting it.
|
||||
The [reservation regression](../../server/src/services/remote-workspace-reservation.test.ts)
|
||||
and [saved-file lifecycle suite](../../server/src/services/remote-workspaces.integration.test.ts)
|
||||
exercise inheritance, access checks, and file continuity with real PostgreSQL.
|
||||
Their filesystem transport is local test execution, not live sandbox/provider proof.
|
||||
|
||||
The Files panel must label **Live workspace** or **Saved copy** with its save
|
||||
time. Confirm browse, preview, and download agree. A missing allocation with
|
||||
unsaved work must report unavailability rather than show an old save as current.
|
||||
After a final save clears dirty state and writer authority, Files must read the
|
||||
current committed saved version even while the old allocation is still recorded
|
||||
or its read transport is unavailable. Confirm the original bytes and Saved copy
|
||||
label; a new writer or dirty state must retain the live-read requirement.
|
||||
Clear the recorded allocation while a saved preview is loading: the pinned copy
|
||||
must remain readable. Epoch, snapshot, source, writer, dirty-state, and foreign
|
||||
or reintroduced location changes must still reject the read. Live reads keep
|
||||
their physical-location fence, and all private saved copies must be removed.
|
||||
Close must retain dirty/unfinished work and reject custom cleanup/teardown
|
||||
commands; a clean saved workspace can release compute while retaining files.
|
||||
Manual runtime commands, jobs, repairs, and service starts must reject remote
|
||||
@@ -235,12 +189,9 @@ Manual: Provision a disposable workspace, wait for readiness, start an available
|
||||
encryption key. Edits after the last save still depend on the sandbox; there
|
||||
is no periodic workspace backup. The experiment does not remove the instance
|
||||
volume or establish zero-outage deployment for other data paths.
|
||||
- Terminal workspace cleanup wakes after committed task/workspace/PR/finalization changes and
|
||||
restores cooldown deadlines at startup. Empty lanes stop scanning. Metadata reads
|
||||
do not inspect storage. Providers without ancestry inspection use finalized HEAD
|
||||
and destination-aware GitHub proof before storage checks. Associated squash PRs
|
||||
need not be recorded manually; wrong HEAD/base, unreachable integration commits,
|
||||
or unavailable credentials retain the workspace. Compatible records share one advisory Git
|
||||
- Terminal workspace cleanup wakes after committed task/workspace/PR changes and
|
||||
restores cooldown deadlines at startup. Empty lanes stop scanning. Metadata
|
||||
reads do not inspect storage. Compatible records share one advisory Git
|
||||
inspection per bounded page, while each record keeps its own delivery check.
|
||||
Destructive cleanup starts a separate Git scan even if an older scan is running.
|
||||
The [worker tests](../../server/src/__tests__/terminal-workspace-work.test.ts)
|
||||
@@ -262,5 +213,4 @@ Capability ID: `workspaces/closure`.
|
||||
Scope: ui
|
||||
Storybook: Close-readiness checks, pending changes/active runs, blocked/pending/error close, retry close and eligible reopening.
|
||||
Production: Confirm owned workspace shutdown, preserved files/Git state and permitted lifecycle transition/reopening; Browser Use session closure is unrelated.
|
||||
Workspace detail and operation-history reads do not inspect Git or remote storage. Delivery is unknown until explicit close readiness or lifecycle inspection. Verify that these reads work during an inspection outage, while destructive close still refuses unverified data.
|
||||
Sources: Source: [ExecutionWorkspaceDetail.tsx](../../ui/src/pages/ExecutionWorkspaceDetail.tsx), [ExecutionWorkspaceCloseDialog.tsx](../../ui/src/components/ExecutionWorkspaceCloseDialog.tsx), [execution-workspaces.ts](../../server/src/routes/execution-workspaces.ts). Tests: [execution-workspaces-routes.test.ts](../../server/src/__tests__/execution-workspaces-routes.test.ts), [execution-workspaces-service.test.ts](../../server/src/__tests__/execution-workspaces-service.test.ts), [execution-workspace-reopen.test.ts](../../server/src/__tests__/execution-workspace-reopen.test.ts)
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
description: Reserve feature-map additions for substantial new features and avoid incidental map updates.
|
||||
globs: "maps/**"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Feature maps require substantial new features
|
||||
|
||||
Applies to changes under `maps/`, especially `maps/feature-map/` and its
|
||||
same-named agent-access companions.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Add a feature recipe, capability ID, sub-feature, entry point, or descriptive
|
||||
expansion only for a substantial new user-facing feature: a distinct,
|
||||
meaningful task that users could not previously perform and that an existing
|
||||
capability does not already cover. A new workflow such as reusable scheduled
|
||||
routines qualifies; an extra sort option in an existing task list does not.
|
||||
- Leave maps unchanged for routine bug fixes, small behavior adjustments, UI or
|
||||
copy polish, additional filters or settings within an existing capability,
|
||||
refactors, performance work, logging, and test changes. Code changes alone do
|
||||
not require a map update, regardless of how many files they touch.
|
||||
- Do not append implementation details, edge-case narratives, regression notes,
|
||||
test results, or PR summaries to existing recipes to document small updates.
|
||||
Keep those in the relevant tests, technical docs, PR, or issue.
|
||||
- Keep additions focused on the new feature and reuse existing capability IDs
|
||||
when they already cover the work. Do not expand unrelated recipes or companion
|
||||
files. When the feature threshold is unclear, leave the maps unchanged.
|
||||
|
||||
## Existing-entry corrections
|
||||
|
||||
Instructions to keep maps synchronized require a minimal correction only when an
|
||||
existing entry would become materially inaccurate, such as a removed entry
|
||||
point, changed access requirement, or obsolete user journey. Correct or remove
|
||||
the affected text in place and preserve stable IDs; this does not justify new
|
||||
capabilities or incidental detail. Explicitly requested map maintenance may fix
|
||||
existing entries but must apply the same threshold to additions.
|
||||
|
||||
## Review
|
||||
|
||||
For every addition, identify the substantial new user capability and why an
|
||||
existing entry cannot cover it. Reject additions for minor updates and unrelated
|
||||
map edits. For corrections, check that the edit fixes a concrete inaccuracy and
|
||||
stays limited to the affected entry.
|
||||
Reference in new issue
Block a user