From 45862dd2102e4aa506712338a70b334b54060b97 Mon Sep 17 00:00:00 2001 From: Dotta <34892728+cryppadotta@users.noreply.github.com> Date: Mon, 5 Oct 2026 21:08:47 -0500 Subject: [PATCH] docs: add a product feature map (#15288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Its user journeys span tasks, agents, projects, connected apps, governance, and CLI operations. > - Existing tests do not provide a shared index of entry points and verification steps. > - Contributors need to see which surfaces a change affects and what evidence exists. > - This pull request adds an optional product feature map with recipes and explicit coverage gaps. > - The map adds no CI checks or required maintenance for future pull requests. > - Contributors can use it to find verification steps and state what they checked. ## Linked Issues or Issue Description **Issue type** Missing documentation. **Where is the issue?** User-journey verification guidance in AGENTS.md and doc/DEVELOPING.md. **What's wrong?** There is no shared index of product features, user entry points, available test evidence, and remaining coverage gaps. Shared components can hide differences between their hosts. **Suggested fix** Add a documentation-only capability index and verification recipes. The format takes inspiration from [Omnigent's feature map](https://github.com/omnigent-ai/omnigent/tree/91acfbbb59f6fc210ff95a9e9428aadd62e06582/feature-map). The recipes describe Paperclip's own behavior and tests. Searched GitHub PRs and issues for `feature map` and `feature-map`. No duplicate change was found. Checked ROADMAP.md. This PR documents existing capabilities. ## What Changed - Added 35 feature recipes, 171 named sub-features, and 91 entry points across product, CLI, operator, and developer surfaces. - Each recipe describes setup, expected results, existing automated evidence, manual verification, and coverage gaps. - Added a dated source snapshot of 185 non-test page TSX modules in 15 areas. The snapshot describes documentation coverage, not runtime health. - Included entry points within existing pages, CLI/API operations, and experimental surfaces. Identified helper-only test evidence where a rendered journey has no automated proof. - Linked the map from AGENTS.md and doc/DEVELOPING.md as an optional reference. - The final diff contains only Markdown and the inventory JSON. It adds no checker, tests, package commands, workflows, dependencies, scheduled work, or mandatory inventory updates. ## Verification - PASS: local documentation links resolve and the inventory JSON parses. Confirmed the final PR diff contains only 39 documentation files. - PASS: `node --test '.github/scripts/tests/*.test.mjs'` — 381 existing tests after removal of the feature-map tests. - PASS: `git diff --check`. - Earlier local build and typecheck passed. The full local test run was stopped after 26 minutes with failures in unchanged chat-channel and native-runner integration tests. It did not complete. These application checks were not repeated for the documentation-only removal. - [CI on the preceding head](https://github.com/paperclipai/paperclip/actions/runs/37398407523) passed all applicable checks. Checks on the final documentation-only head are pending. - PASS: Greptile review on final head `45c4b0aeb26540324825da43e81bee2336ad1c1f` is 5/5. There are no unresolved findings. - Live product/provider journeys were not run to author the map. The recipes identify available evidence and manual steps, not new qualification results. ## Risks Low product risk: the PR changes documentation only. Recipes and the source snapshot can become stale. Maintenance is optional and based on review. Linked tests do not prove that every documented journey works. The map states remaining coverage gaps. ## Model Used OpenAI Codex, GPT-6 family, with repository inspection, reasoning, tool use, and code execution. The exact serving model ID and context window were not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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 --- AGENTS.md | 4 + doc/DEVELOPING.md | 5 + feature-map/README.md | 177 +++++++++++ feature-map/access.md | 55 ++++ feature-map/activity.md | 45 +++ feature-map/agent-chat.md | 54 ++++ feature-map/agents.md | 55 ++++ feature-map/app-permissions.md | 45 +++ feature-map/budgets-costs.md | 44 +++ feature-map/cases.md | 43 +++ feature-map/chat-channels.md | 45 +++ feature-map/cli-operations.md | 55 ++++ feature-map/companies.md | 44 +++ feature-map/connection-setup.md | 150 +++++++++ feature-map/coverage.json | 401 +++++++++++++++++++++++++ feature-map/developer-labs.md | 43 +++ feature-map/documents-artifacts.md | 55 ++++ feature-map/execution-environments.md | 45 +++ feature-map/gateways-profiles.md | 45 +++ feature-map/goals.md | 42 +++ feature-map/inbox-search.md | 54 ++++ feature-map/instance-operations.md | 45 +++ feature-map/navigation-preferences.md | 45 +++ feature-map/onboarding.md | 45 +++ feature-map/pipelines.md | 44 +++ feature-map/plugins.md | 44 +++ feature-map/projects.md | 44 +++ feature-map/questions-and-approvals.md | 182 +++++++++++ feature-map/recovery.md | 159 ++++++++++ feature-map/routines.md | 45 +++ feature-map/runs-adapters.md | 44 +++ feature-map/secrets.md | 45 +++ feature-map/skills.md | 55 ++++ feature-map/status-cards.md | 44 +++ feature-map/steering.md | 135 +++++++++ feature-map/task-coordination.md | 44 +++ feature-map/tasks.md | 55 ++++ feature-map/teams.md | 44 +++ feature-map/workspaces.md | 45 +++ 39 files changed, 2670 insertions(+) create mode 100644 feature-map/README.md create mode 100644 feature-map/access.md create mode 100644 feature-map/activity.md create mode 100644 feature-map/agent-chat.md create mode 100644 feature-map/agents.md create mode 100644 feature-map/app-permissions.md create mode 100644 feature-map/budgets-costs.md create mode 100644 feature-map/cases.md create mode 100644 feature-map/chat-channels.md create mode 100644 feature-map/cli-operations.md create mode 100644 feature-map/companies.md create mode 100644 feature-map/connection-setup.md create mode 100644 feature-map/coverage.json create mode 100644 feature-map/developer-labs.md create mode 100644 feature-map/documents-artifacts.md create mode 100644 feature-map/execution-environments.md create mode 100644 feature-map/gateways-profiles.md create mode 100644 feature-map/goals.md create mode 100644 feature-map/inbox-search.md create mode 100644 feature-map/instance-operations.md create mode 100644 feature-map/navigation-preferences.md create mode 100644 feature-map/onboarding.md create mode 100644 feature-map/pipelines.md create mode 100644 feature-map/plugins.md create mode 100644 feature-map/projects.md create mode 100644 feature-map/questions-and-approvals.md create mode 100644 feature-map/recovery.md create mode 100644 feature-map/routines.md create mode 100644 feature-map/runs-adapters.md create mode 100644 feature-map/secrets.md create mode 100644 feature-map/skills.md create mode 100644 feature-map/status-cards.md create mode 100644 feature-map/steering.md create mode 100644 feature-map/task-coordination.md create mode 100644 feature-map/tasks.md create mode 100644 feature-map/teams.md create mode 100644 feature-map/workspaces.md diff --git a/AGENTS.md b/AGENTS.md index c957ca41ea..53f25d6d51 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -152,6 +152,10 @@ Notes: ## 7. Verification Before Hand-off +[feature-map/README.md](feature-map/README.md) is an optional reference for user +entry points, verification recipes, and coverage gaps. The map records coverage +scope, not proof that a live journey passed. + Default local/agent test path: ```sh diff --git a/doc/DEVELOPING.md b/doc/DEVELOPING.md index c30e261158..fb3f6d9447 100644 --- a/doc/DEVELOPING.md +++ b/doc/DEVELOPING.md @@ -460,6 +460,11 @@ npx paperclipai allowed-hostname dotta-macbook-pro ## Test Commands +The [feature map](../feature-map/README.md) is an optional reference for user +entry points, targeted tests, manual verification recipes, and coverage gaps. +Its page inventory is a source snapshot. The documented journeys have separate +verification steps and do not run automatically from the map. + Use the cheap local default unless you are specifically working on browser flows: ```sh diff --git a/feature-map/README.md b/feature-map/README.md new file mode 100644 index 0000000000..b38d7fb650 --- /dev/null +++ b/feature-map/README.md @@ -0,0 +1,177 @@ +# Paperclip feature map + +Start here when reproducing a user-facing bug, verifying a change, or deciding +which surfaces a fix must cover. Each recipe describes what a person can do, +where they can do it, the expected result, and the evidence needed to verify it. +Product behavior is still governed by [the implementation spec](../doc/SPEC-implementation.md). + +## Features + +The map is organized by user capability, not by source file. It covers **35 feature +families** across the product, CLI, and operator workflows, checked against source +on 2026-10-05. Experimental and developer-only surfaces are labeled explicitly. +Each recipe includes sub-features, current entry points, automated evidence, +manual verification steps, and gotchas. + +### Getting started and access + +| Feature | What it covers | +| --- | --- | +| [Onboarding and first work](./onboarding.md) | Instance setup, company wizard, first agent and task. | +| [Login, invitations, and access](./access.md) | Sessions, bootstrap, membership, roles, and CLI authorization. | +| [Companies and portability](./companies.md) | Company switching/settings, archival, package import/export. | + +### Tasks and conversations + +| Feature | What it covers | +| --- | --- | +| [Task creation and lifecycle](./tasks.md) | Creation, assignment, lists, properties, comments, and completion. | +| [Delegation, dependencies, and signoff](./task-coordination.md) | Child work, prerequisites, reviewers, and task-tree controls. | +| [Inbox, decisions, and search](./inbox-search.md) | Personal triage, decision queues, unread/blocked views, and search. | +| [Agent conversations and project handoff](./agent-chat.md) | Persistent conversations, discovery, handoff, and gated board chat. | +| [Questions and approvals](./questions-and-approvals.md) | Question/plan responses, formal approvals, and app-tool review. | +| [Steering and queued messages](./steering.md) | Follow-ups, queue edits, interruption, and pause/resume. | +| [Documents, attachments, and work products](./documents-artifacts.md) | Versioned documents, annotations, files, outputs, and artifact library. | + +### Agents and reusable capabilities + +| Feature | What it covers | +| --- | --- | +| [Hiring, configuration, and organization](./agents.md) | Agent identity, instructions, reporting lines, lifecycle, and built-ins. | +| [Runs, harnesses, and model accounts](./runs-adapters.md) | Adapter/model setup, account validation, transcripts, and run history. | +| [Skills and Skill Studio](./skills.md) | Discovery, sources, authoring, revisions, tests, and agent policies. | +| [Team packages and installation](./teams.md) | Catalog preview/install via CLI/API; catalog UI availability called out. | + +### Projects and execution + +| Feature | What it covers | +| --- | --- | +| [Projects and repositories](./projects.md) | Project lifecycle, task context, repository configuration, and defaults. | +| [Goals and work alignment](./goals.md) | Goal hierarchy, ownership, status, and project/task context. | +| [Workspaces, services, and files](./workspaces.md) | Provisioning, task bindings, services/logs, Git/files, and closure. | +| [Execution environments](./execution-environments.md) | Local, SSH, sandbox providers, target probes, and custom images. | +| [Recovery](./recovery.md) | Stopped work, workspace repair, bounded continuation, and reconnect. | + +### Apps, channels, and extensions + +| Feature | What it covers | +| --- | --- | +| [Connection setup](./connection-setup.md) | Catalog, MCP links, task requests, authentication, and setup resumption. | +| [App access and action permissions](./app-permissions.md) | Agent grants, off/ask/allowed actions, discovery, tests, and revocation. | +| [External chat and email](./chat-channels.md) | Provider-specific identity, threads, files, delivery, and endpoint upkeep. | +| [Tool gateways and access profiles](./gateways-profiles.md) | Tool exposure, client configuration, tokens, profiles, and activity. | +| [Secrets and proposals](./secrets.md) | Company/user credentials, grants, proposals, and vault import. | +| [Plugins](./plugins.md) | Installation/configuration, contributed pages/tools, and lifecycle. | + +### Automation and structured work + +| Feature | What it covers | +| --- | --- | +| [Routines, schedules, and triggers](./routines.md) | Definitions, variables, scheduled/webhook/manual runs, and history. | +| [Pipelines, review queues, and learnings](./pipelines.md) | Experimental stages, automation, items, review, and learning records. | +| [Cases](./cases.md) | Experimental structured fields, relationships, revisions, and task links. | +| [Status cards](./status-cards.md) | Experimental summaries, watched work, refresh history, and settings. | + +### Oversight and operation + +| Feature | What it covers | +| --- | --- | +| [Costs and budgets](./budgets-costs.md) | Spend reports, scoped limits, incidents, hard stops, and resumption. | +| [Dashboards and audit trails](./activity.md) | Company health, live work, activity, runs, routines, and timeline. | +| [Navigation, profile, and announcements](./navigation-preferences.md) | Sidebar state, favorites/recents, personal identity, and dismissals. | +| [Instance operations](./instance-operations.md) | Installation, updates, service health, configuration, and backups. | +| [CLI/API and local worktrees](./cli-operations.md) | Explicit context, resource commands, outputs, runs, and isolated instances. | + +### Contributor surfaces + +| Feature | What it covers | +| --- | --- | +| [Developer previews and diagnostic labs](./developer-labs.md) | Design examples, interaction fixtures, performance checks; not production acceptance. | + +These are verification instructions, not a claim that every journey passed a live +test. A component test proves its component; a scripted provider proves that +fixture integration. Record executed results separately from the map. + +## Before driving a journey + +1. Use this checkout's [isolated test drive](../doc/DEVELOPING.md#one-command-isolated-manual-test-drive) + for manual product checks. It creates a temporary instance and prints its URL + and data directory. Do not guess that a server on port 3100 belongs to you. +2. Record the commit, URL, company, login role, relevant experimental settings, + adapter, runtime mode, and live versus simulated dependencies. Use disposable + tasks and provider resources. A fresh test drive creates a company and CEO, + but no task or first run. +3. Use the current navigation and company prefix. Paths in recipes omit that + prefix. Record whether the streamlined or production shell is selected; + Agent Chat, chat connectors, and the combined Inbox/Tasks view have separate + gates. A hidden surface is an unmet prerequisite, not a successful test. +4. Run the smallest relevant test first. Vitest commands below run from the + repository root after installing dependencies. Playwright recipes use their + named configuration and its isolated environment, not an unrelated running + instance. Reserve expensive runner/provider tests for the behavior at issue. +5. Exercise the actual user action, inspect its result, reload, and verify the + persisted state or continuation. Use read-only API checks to corroborate UI + evidence; creating state through the API does not prove the creation UI. + +For agent-driven acceptance work, the existing +[dev-workspace run/verify skill](../.agents/skills/paperclip-dev-workspace-run-verify-fix/SKILL.md) +and [evaluation skill](../.agents/skills/paperclip-evals/SKILL.md) describe runtime +ownership and evidence handling. Reuse them; this map introduces no environment +launcher, credentials, scheduled job, or second test framework. + +## Evidence contract + +Report each entry point as **passed**, **failed**, **blocked** (with its missing +prerequisite), or **not run**. Include the feature filename and entry-point ID, +commit/environment, user action, expected and observed result, command/exit code, +and evidence links. Screenshots or traces should show both the action and the +discriminating result. Include task/run/request IDs when relevant, without secrets. + +A fix is verified across its affected surfaces only when each has evidence or +an explicit reason it does not apply. Shared code alone does not prove parity. +Keep product regressions visible; do not change the recipe to bless a failure. +For Paperclip-assigned work, attach evidence through the +[artifact workflow](../doc/AGENT-ARTIFACTS.md). + +## Inventory and remaining depth + +[The UI coverage inventory](./coverage.json) accounts for every non-test TSX +module under `ui/src/pages`, including supporting panels, legacy variants, and +labs. Every product area now links to concrete recipes. **Partial** means the +area still has the named variant or workflow gaps; **unmapped** is reserved for +an area with no recipe. These statuses describe documentation, not runtime health. + +The page inventory is a source snapshot dated 2026-10-05. The map also +includes entry points hosted inside other modules (pipeline Review Queue and +Learnings, task documents, onboarding), CLI-only operations, and operator work. +The team recipe explicitly distinguishes the current CLI/API path from catalog +UI components without a current top-level route. Refer to [route registration](../ui/src/App.tsx) +and the [CLI registry](../cli/src/index.ts) when changing reachability. + +Remaining depth includes complete provider/auth/attachment matrices, every +harness/model/environment capability combination, third-party plugin features, +and every role/error/mobile/legacy-shell permutation. The recipes name relevant +gaps instead of equating source presence with a working user journey. The index +can include capabilities that do not add a page file. + +## Maintaining the reference + +The map is documentation only. It adds no CI checks, automatic journey execution, +or required inventory updates for future pull requests. + +When maintaining a recipe, compare its entry points and expected results with +the current source. Check that linked tests still exercise the stated behavior +and that local references still exist. Refresh the inventory snapshot when it +helps explain the current product. Maintenance is optional and review-based. + +Each recipe starts with an H1 and a user-visible description, then exactly: + +1. **Sub-features** — stable backticked IDs and observable behavior/states. +2. **How to get to it (user POV)** — one H3 backticked entry-point ID per surface. +3. **Driving it** — starts with `Preconditions:`; repeat each entry-point H3, + with `Automated:` and `Manual:` paragraphs. Name test scope and gaps honestly. +4. **Gotchas** — misleading look-alikes, feature gates, and invalid evidence. + +The format is inspired by +[Omnigent's feature map](https://github.com/omnigent-ai/omnigent/tree/91acfbbb59f6fc210ff95a9e9428aadd62e06582/feature-map). +Paperclip's recipes and checks follow its own task model and test infrastructure. diff --git a/feature-map/access.md b/feature-map/access.md new file mode 100644 index 0000000000..d7248c8b63 --- /dev/null +++ b/feature-map/access.md @@ -0,0 +1,55 @@ +# Login, invitations, and access + +People and agents enter the correct instance and company with the permissions granted to their identity. Login, membership, resource access, and CLI authorization have separate controls. + +Implementation: [auth page](../ui/src/pages/Auth.tsx), [company members](../ui/src/pages/CompanyAccess.tsx), [invitation](../ui/src/pages/InviteLanding.tsx). + +## Sub-features + +- `login`: sign in or claim the board in the configured deployment mode. +- `invitations`: join through a valid invite and handle expired or already-used links. +- `membership`: review join requests and manage company/instance membership and permissions. +- `resources`: respect company and resource boundaries on deep links and mutations. +- `cli-auth`: authorize a CLI session and revoke or replace credentials. + +## How to get to it (user POV) + +### `login` + +Open `/auth`; first-owner bootstrap uses `/board-claim/:token` when configured. + +### `invite-members` + +Open `/invite/:token`; operators manage members in company settings and join requests at `/inbox/requests`. + +### `cli-authorization` + +Start the CLI auth/connect flow and approve its `/cli-auth/:id` browser page; instance access is under Settings when visible. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). For login tests use authenticated mode and two test users; local-trusted mode does not prove session enforcement. Use two companies for isolation checks. + +### `login` + +Automated: [auth UI](../ui/src/pages/Auth.test.tsx) and [session routes](../server/src/__tests__/auth-session-route.test.ts) cover their respective layers. + +Manual: Sign in, reload a company deep link, sign out, and revisit it. Confirm the browser requests authentication rather than showing cached company data. Test an invalid claim separately on disposable state. + +### `invite-members` + +Automated: [member UI](../ui/src/pages/CompanyAccess.test.tsx) and [invite replay](../server/src/__tests__/invite-accept-replay.test.ts) provide component and route evidence. + +Manual: Accept an invite as the intended user, inspect the resulting company and permissions, then reuse and expire disposable invites. Change a member permission, reload as that member, and verify a denied operation on another company remains denied. + +### `cli-authorization` + +Automated: [board auth client](../cli/src/__tests__/board-auth.test.ts) and [token commands](../cli/src/__tests__/token.test.ts) cover the client contracts. + +Manual: Authorize the intended CLI context, make a read-only company request, then revoke its token and retry. Verify failure is explicit and does not silently fall back to another identity. + +## Gotchas + +- Settings visibility is not authorization; direct requests still need permission checks. +- An agent bearer key must not gain another company’s access. +- Never put invite tokens, session cookies, or API keys in verification evidence. diff --git a/feature-map/activity.md b/feature-map/activity.md new file mode 100644 index 0000000000..a50206a9fc --- /dev/null +++ b/feature-map/activity.md @@ -0,0 +1,45 @@ +# Dashboards, activity, and audit trails + +People inspect company health, recent activity, run history, and routine activity, then follow evidence back to the task or agent responsible. + +Implementation: [dashboard](../ui/src/pages/Dashboard.tsx), [live dashboard](../ui/src/pages/DashboardLive.tsx), [audit hub](../ui/src/pages/audit/AuditHub.tsx). + +## Sub-features + +- `overview`: inspect the company dashboard and live-work summary. +- `activity`: filter and page through recorded actor/resource events. +- `runs`: find executions and follow their task/agent context. +- `routine-audit`: inspect routine execution activity separately from its definition. +- `timeline`: use the available timeline view to understand work over time. + +## How to get to it (user POV) + +### `dashboard` + +Open `/dashboard` or `/dashboard/live`. + +### `activity-audit` + +Open `/activity`, `/activity/runs`, or `/activity/timeline` in the streamlined shell; legacy routes may redirect. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Prepare known task mutations and completed/failed runs in a disposable company, recording their IDs and actors. + +### `dashboard` + +Automated: [dashboard service](../server/src/__tests__/dashboard-service.test.ts) covers server aggregation; [dashboard helpers](../ui/src/pages/Dashboard.test.ts) is narrower UI helper coverage. + +Manual: Compare the dashboard with the known fixture tasks and runs. Start and finish a small task, refresh/reload, and verify the summary changes and links reach the right records. Exercise empty data and a failed fetch. + +### `activity-audit` + +Automated: [activity service](../server/src/__tests__/activity-service.test.ts), [audit runs](../ui/src/pages/audit/AuditRuns.test.tsx), and [routine audit](../ui/src/pages/audit/RoutineAuditActivity.test.tsx) cover these separate data/host layers. + +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. + +## Gotchas + +- Audit/activity events, run-log rows, first-party Telemetry, and operator OpenTelemetry traces are separate data paths. +- A healthy stream or dashboard counter alone does not prove task success. +- Cost and budget reports have their own [recipe](./budgets-costs.md). diff --git a/feature-map/agent-chat.md b/feature-map/agent-chat.md new file mode 100644 index 0000000000..e47de311b5 --- /dev/null +++ b/feature-map/agent-chat.md @@ -0,0 +1,54 @@ +# Agent conversations and project handoff + +A person can hold a persistent conversation with an agent, return to its history, and hand useful work into a project or task. The gated conference-room chat is a separate conversation surface. + +Implementation: [agent chat](../ui/src/pages/AgentChat.tsx), [chat landing](../ui/src/pages/AgentChats.tsx), [conference room](../ui/src/pages/BoardChat.tsx). + +## Sub-features + +- `discovery`: find an agent and reopen an accessible recent conversation. +- `history`: send messages, inspect replies/files, and return to the same conversation. +- `handoff`: create or identify a project/task from chat and follow the resulting work. +- `conference-room`: use the separately gated board chat without assuming parity with agent chat. + +## How to get to it (user POV) + +### `agent-conversation` + +Open `/chats`, choose an agent, or use `/chats/:agentRef` and its conversation sidebar. + +### `project-handoff` + +Ask for project work in Agent Chat and follow its created project/task links. + +### `conference-room` + +Open `/board-chat` only when its conference-room gate is enabled. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enable the applicable chat feature, use a configured test agent, and distinguish model replies from a mocked conversation fixture. + +### `agent-conversation` + +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. + +Manual: Start a conversation, send a recognizable request, and inspect its reply. Navigate away and reopen the same history. Test a new conversation, unavailable historical agent, and an inaccessible saved conversation; verify no cross-user or cross-company history appears. + +### `project-handoff` + +Automated: [chat project tools](../server/src/__tests__/chat-project-tools.test.ts) checks tool contracts; live model choice and UI handoff require a manual run. + +Manual: Ask the configured agent to create bounded project work, inspect the proposed/created target, and open the resulting task. Verify the request context and intended project survived and the task produces a useful output. + +### `conference-room` + +Automated: [board chat gate](../server/src/__tests__/board-chat-route-feature-flag.test.ts) proves route gating, not a live conversation. + +Manual: Check disabled access first, enable in the disposable instance, then send and reload a conversation. Inspect the actual responding agent and persisted history; report this result separately from Agent Chat. + +## Gotchas + +- 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. diff --git a/feature-map/agents.md b/feature-map/agents.md new file mode 100644 index 0000000000..a1633a52da --- /dev/null +++ b/feature-map/agents.md @@ -0,0 +1,55 @@ +# Hiring, agent configuration, and organization + +Operators hire agents, configure their identity and instructions, assign reporting relationships, and manage their lifecycle. Built-in agents have their own setup and lifecycle constraints. + +Implementation: [hiring](../ui/src/pages/NewAgent.tsx), [configuration](../ui/src/components/AgentConfigForm.tsx), [organization](../ui/src/pages/OrgChart.tsx). + +## Sub-features + +- `hire`: choose role, manager, adapter, model, and required account settings. +- `instructions`: edit agent configuration and instruction files with durable revisions. +- `organization`: inspect and change reporting relationships through supported controls. +- `lifecycle`: pause/resume or retire an agent while preserving history. +- `built-in`: configure required agents without treating them as ordinary removable hires. + +## How to get to it (user POV) + +### `hire-agent` + +Use New agent from the roster or `/agents/new`. + +### `agent-configuration` + +Open `/agents/:agentId` and the configuration/instruction surfaces it exposes. + +### `organization` + +Use the roster’s organization view; `/org` redirects to the roster in the streamlined shell. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a disposable company and supported adapter; hiring may require a formal approval. + +### `hire-agent` + +Automated: [new agent page](../ui/src/pages/NewAgent.test.tsx) and [configuration form](../ui/src/components/AgentConfigForm.render.test.tsx) cover mocked UI behavior. + +Manual: Hire an agent with a distinct name and role. Complete any required approval, reload the roster, and open its configuration. Confirm manager, adapter, and model persisted; run a small task to prove execution readiness. + +### `agent-configuration` + +Automated: [instruction service](../server/src/__tests__/agent-instructions-service.test.ts) and [instruction revisions](../server/src/__tests__/agent-instruction-revisions.test.ts) cover file/revision contracts. + +Manual: Save a harmless instruction edit, reload, and verify its revision and effect in the next eligible run. Pause and resume the disposable agent; confirm pause prevents new work and does not erase previous runs. + +### `organization` + +Automated: [org chart](../ui/src/pages/OrgChart.test.tsx) is component evidence. Built-in setup also has [configuration modal tests](../ui/src/components/ConfigureBuiltInAgentModal.test.tsx). + +Manual: Inspect a manager and report, change the relationship through the offered controls, and reload both views. Exercise a rejected invalid relationship. Configure a built-in agent and verify it retains its required identity and restrictions. + +## Gotchas + +- A roster entry is not proof of an authenticated or invokable adapter. +- Pending hires may live in approval/task surfaces rather than the active roster. +- Skill and tool grants are separate: see [skills](./skills.md) and [app permissions](./app-permissions.md). diff --git a/feature-map/app-permissions.md b/feature-map/app-permissions.md new file mode 100644 index 0000000000..fd8a825c51 --- /dev/null +++ b/feature-map/app-permissions.md @@ -0,0 +1,45 @@ +# App access, action permissions, and testing + +After connecting an app, an operator decides which agents may use it and whether each action is off, requires approval, or is allowed. Activity and action tests help verify the resulting access. + +Implementation: [app detail](../ui/src/pages/apps/AppDetail.tsx), [permissions](../ui/src/pages/apps/app-detail/PermissionsPanel.tsx), [activity](../ui/src/pages/apps/app-detail/ActivityPanel.tsx). + +## Sub-features + +- `agent-access`: grant the connection to all or selected eligible agents. +- `action-policy`: set off/ask/allowed independently for available actions. +- `catalog-change`: review newly discovered/quarantined actions before enabling them. +- `test-action`: choose an actor and inputs and inspect a real action result. +- `account-maintenance`: inspect accounts, reconnect/revoke, and review connection activity. + +## How to get to it (user POV) + +### `permissions` + +Open an app at `/apps/:connectionId/permissions`; this is the default connected-app view. + +### `test-and-maintain` + +Use the action test control in Permissions, then the connection’s Activity and available account/advanced controls. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Prepare a connection to a fixture or test provider, two agents, and a harmless action. Record provider and credential ownership. + +### `permissions` + +Automated: [app detail](../ui/src/pages/apps/AppDetail.test.tsx) covers agent/action controls, quarantined actions, and navigation using mocked requests. + +Manual: Grant one agent access, leave another excluded, and exercise off, ask, and allowed states for a harmless action. Reload between changes. Verify actual denied calls stay denied and ask-first creates a decision rather than executing early. + +### `test-and-maintain` + +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. + +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. + +## Gotchas + +- Connected does not imply an agent has access or an action is allowed. +- Credential-only connections may replace tool-action controls with account-specific controls. +- See [connection setup](./connection-setup.md) for auth and [questions and approvals](./questions-and-approvals.md) for pending action review. diff --git a/feature-map/budgets-costs.md b/feature-map/budgets-costs.md new file mode 100644 index 0000000000..e1a1efc573 --- /dev/null +++ b/feature-map/budgets-costs.md @@ -0,0 +1,44 @@ +# Costs, budgets, and spending controls + +Operators inspect recorded spend and configure budget controls for the company, projects, and agents. Hard stops pause or prevent eligible work until the governing incident is resolved. + +Implementation: [costs and budget host](../ui/src/pages/Costs.tsx), [audit hub](../ui/src/pages/audit/AuditHub.tsx). + +## Sub-features + +- `cost-reporting`: inspect spend by the offered time range and resource dimensions. +- `budgets`: configure supported company/project/agent limits and inspect usage. +- `incidents`: distinguish warnings, hard stops, and manual pauses. +- `resolution`: raise or resolve a budget incident through authorized controls and verify resumption. + +## How to get to it (user POV) + +### `cost-overview` + +Use Activity → Costs/Budgets in the streamlined shell, `/costs` in the production shell, or scoped project/agent budget panels. + +### `budget-enforcement` + +Open the governing budget configuration and any resulting budget incident card. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use synthetic low-cost events and small disposable budgets. Do not buy model usage merely to hit a threshold. + +### `cost-overview` + +Automated: [costs service](../server/src/__tests__/costs-service.test.ts) covers cost contracts; [embedded costs UI](../ui/src/pages/Costs.test.tsx) has narrow Audit-host coverage. + +Manual: Inspect a known fixture run and reconcile its recorded spend with the selected report period and resource. Switch company/project filters and reload. Check empty and unavailable cost data without treating missing data as zero spend. + +### `budget-enforcement` + +Automated: [budget service](../server/src/__tests__/budgets-service.test.ts) exercises soft incidents, hard stops, scope, and valid budget raises. + +Manual: Create a small fixture budget, cross its threshold with synthetic recorded spend, and verify the warning or hard-stop state. Attempt new work and confirm it is gated. Raise the correct budget through an authorized action and verify eligible continuation without clearing unrelated manual pauses. + +## Gotchas + +- Paperclip cost accounting is not a provider invoice or a promise about externally billed spend. +- Company, project, and agent gates can overlap; fixing one may leave another active. +- A successful retry must not bypass an unresolved budget hold. diff --git a/feature-map/cases.md b/feature-map/cases.md new file mode 100644 index 0000000000..10cde78e5e --- /dev/null +++ b/feature-map/cases.md @@ -0,0 +1,43 @@ +# Cases and structured work records + +The cases experiment exposes structured records with types, fields, parent/child relationships, activity, revisions, and related task work. + +Implementation: [case list](../ui/src/pages/Cases.tsx), [case detail](../ui/src/pages/CaseDetail.tsx). + +## Sub-features + +- `browse`: search, filter, sort, group, and navigate case records. +- `structure`: inspect fields and parent/child relationships without losing matching descendants. +- `history`: inspect revisions and activity for a record. +- `task-links`: follow work associated with a case in both directions. + +## How to get to it (user POV) + +### `case-list` + +Open `/cases` and switch between available grouped/tree views. + +### `case-record` + +Open `/cases/:caseIdentifier` or a task’s linked case. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enable cases and prepare related records with different types/statuses plus an associated task. + +### `case-list` + +Automated: [case list](../ui/src/pages/Cases.test.tsx) covers filters, persisted view state, and keyboard/tree behavior with mocked data. + +Manual: Search for a child, verify its parent context remains understandable, change filters/grouping/columns, and reload. Open the record by keyboard and direct link. Include empty results and terminal records. + +### `case-record` + +Automated: [case routes](../server/src/__tests__/cases-routes.test.ts) covers API behavior; [case fields](../ui/src/components/CaseFieldsPanel.test.tsx) covers field UI separately. + +Manual: Edit an offered field, reload, inspect its revision/activity, and follow child and task links. Verify cross-company and invalid field changes fail clearly. Distinguish a pipeline-owned item from a stand-alone case. + +## Gotchas + +- A case is not a task execution; inspect linked tasks to prove work occurred. +- Feature gating and case-type schema determine which actions are available. diff --git a/feature-map/chat-channels.md b/feature-map/chat-channels.md new file mode 100644 index 0000000000..3399965dca --- /dev/null +++ b/feature-map/chat-channels.md @@ -0,0 +1,45 @@ +# External chat and email conversations + +People can talk to an assigned agent through configured external channels, bind their identity, exchange files, and inspect delivery state. Each provider has a different identity, threading, and attachment contract. + +Implementation: [endpoint setup](../ui/src/pages/apps/chat/ChatEndpointSetup.tsx), [endpoint detail](../ui/src/pages/apps/chat/ChatEndpointDetail.tsx), [email setup](../ui/src/pages/apps/chat/EmailEndpointSetup.tsx). + +## Sub-features + +- `providers`: configure the available Slack, Discord, Microsoft Teams, Telegram, GitHub, AgentMail, and experimental iMessage Photon paths; availability still depends on gates and provider support. +- `identity`: link the external sender to the intended authorized Paperclip identity. +- `conversation`: route inbound messages to the selected agent and send replies to the correct thread. +- `attachments`: transfer supported files with inspectable delivery and failure states. +- `lifecycle`: inspect endpoint activity, repair auth, and disable delivery when required. + +## How to get to it (user POV) + +### `external-thread` + +Message the configured bot/address from its external provider and follow the corresponding Paperclip conversation/task. + +### `endpoint-management` + +Open `/apps/chat/:endpointId/settings` and the endpoint’s other available tabs; identity confirmation uses `/chat-identity/confirm`. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enable chat connectors and use a test provider account/channel with permission to send messages. Setup is covered in [connection setup](./connection-setup.md). + +### `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. + +Manual: For each supported provider being changed, send a unique message, verify the intended agent/company receives it, and inspect the actual external reply in the original thread. Repeat with an unlinked/unauthorized sender, duplicate inbound delivery, and one supported attachment. Record provider-specific results separately. + +### `endpoint-management` + +Automated: [channel integration](../server/src/__tests__/chat-channels.integration.test.ts) covers shared endpoint/delivery behavior; live credential repair and provider ownership remain manual checks. + +Manual: Inspect the bound agent and identity, recent activity, and delivery failure details. Repair a disposable credential, retry a safe message when offered, and verify exactly one external reply. Disable the endpoint and confirm new traffic is not silently processed. + +## Gotchas + +- One provider’s passing fixture does not qualify another provider or live delivery. +- An accepted send request does not prove the recipient received the message or file. +- Use [steering](./steering.md) and [questions](./questions-and-approvals.md) for their channel-specific interaction checks. diff --git a/feature-map/cli-operations.md b/feature-map/cli-operations.md new file mode 100644 index 0000000000..34c95f01c6 --- /dev/null +++ b/feature-map/cli-operations.md @@ -0,0 +1,55 @@ +# CLI, API clients, and local worktrees + +Operators and agents can work through explicit CLI/API context, manage domain resources, inspect runs, and create isolated local worktree instances for development. + +Implementation: [command registry](../cli/src/index.ts), [client context](../cli/src/commands/client/context.ts), [worktree commands](../cli/src/commands/worktree.ts). + +## Sub-features + +- `context`: choose instance/API base, profile, identity, and company explicitly. +- `domain-commands`: read/write tasks, agents, projects, goals, approvals, routines, and other registered resources. +- `outputs`: work with documents/assets/skills and inspect machine-readable results. +- `run-controls`: invoke/inspect supported runs and observe actual outcomes. +- `worktree-instances`: initialize, seed, diagnose, and clean up only an owned development instance. + +## How to get to it (user POV) + +### `client-context` + +Use `paperclipai context show/list/use/set`, auth/connect, and the registered resource command help. + +### `subresources-and-runs` + +Use issue subresource, asset/skill, and run/heartbeat commands exposed by the CLI help. + +### `worktree-instance` + +Use the documented worktree/test-drive commands in an owned checkout; inspect `paperclipai worktree --help` first. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use `--help` from the checked-out CLI to discover exact arguments. Select a disposable company and isolated context; do not inherit an unknown API target. + +### `client-context` + +Automated: [context](../cli/src/__tests__/context.test.ts), [HTTP client](../cli/src/__tests__/http.test.ts), and [operations parity](../cli/src/__tests__/operations-parity.test.ts) cover client contracts, not every live endpoint. + +Manual: Inspect the selected context and identity, list the disposable company’s resources, create a harmless task through the supported command, and verify it in the browser. Exercise an invalid token and wrong-company resource. Inspect JSON output and nonzero errors rather than only printed success text. + +### `subresources-and-runs` + +Automated: [issue subresources](../cli/src/__tests__/issue-subresources.test.ts) and [asset/skill parity](../cli/src/__tests__/admin-asset-skill-parity.test.ts) cover command/API contracts. + +Manual: Write a small task document or attach a fixture using the supported command, open it in the UI, and compare contents. Invoke eligible test work, inspect the resulting run ID/status/output, and verify denial when the actor lacks permission. + +### `worktree-instance` + +Automated: [worktree commands](../cli/src/__tests__/worktree.test.ts) and [test drive](../cli/src/__tests__/test-drive.test.ts) cover isolation/setup contracts. + +Manual: Initialize an owned disposable worktree instance, inspect its printed paths and ports, verify health and login, and confirm any seed data belongs to the intended source. Stop and clean up only that instance; inspect preserved work before deleting any checkout. + +## Gotchas + +- API success proves its contract, not the equivalent browser creation journey. +- The CLI command registry is broader than the UI page inventory; new command families need a recipe review. +- See [instance operations](./instance-operations.md) for install/update/backup and feature-specific recipes for domain behavior. diff --git a/feature-map/companies.md b/feature-map/companies.md new file mode 100644 index 0000000000..d0ce685318 --- /dev/null +++ b/feature-map/companies.md @@ -0,0 +1,44 @@ +# Companies and portability + +An operator can switch between companies, change their identity and settings, archive them, and preview an import or export. Each company remains a separate scope for work and agents. + +Implementation: [companies](../ui/src/pages/Companies.tsx), [settings](../ui/src/pages/CompanySettings.tsx), [import](../ui/src/pages/CompanyImport.tsx), [export](../ui/src/pages/CompanyExport.tsx). + +## Sub-features + +- `selection`: create/select a company and keep navigation in its scope. +- `identity`: update company identity and configured settings. +- `archive`: archive and restore through the available controls without confusing archival with deletion. +- `portability`: preview a company package and inspect imported agents, projects, skills, and conflicts. + +## How to get to it (user POV) + +### `company-switcher` + +Use the company switcher or `/companies`, then enter company Settings. + +### `package-transfer` + +Use `/company/export` and `/company/import` where enabled, or the corresponding CLI company commands. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use two disposable companies and a small package fixture. Record cloud-managed restrictions and visible settings gates. + +### `company-switcher` + +Automated: [company list](../ui/src/pages/Companies.test.tsx) and [archive UI](../ui/src/pages/CompanySettingsArchive.test.tsx) cover UI behavior with mocks. + +Manual: Create or select a company, rename it, and reload. Switch to the second company and back; verify tasks, agents, and settings follow the selection. Archive the disposable company and verify its visibility and offered restoration path. + +### `package-transfer` + +Automated: [portability routes](../server/src/__tests__/company-portability-routes.test.ts) and [CLI import/export](../cli/src/__tests__/company-import-export-e2e.test.ts) cover package and command behavior, not every external Git host. + +Manual: Export a small company, inspect the package preview, and import into a disposable target. Verify counts, references, conflict choices, and agent configuration. Run one imported task after supplying its required local credentials. Confirm source company data is unchanged. + +## Gotchas + +- Package presence does not prove a runnable imported company; credentials and environment bindings need separate verification. +- Company deletion is a distinct gated operation; do not use it as the archive test. +- Settings hidden in a managed deployment should be recorded as unavailable, not bypassed. diff --git a/feature-map/connection-setup.md b/feature-map/connection-setup.md new file mode 100644 index 0000000000..00c9328a9a --- /dev/null +++ b/feature-map/connection-setup.md @@ -0,0 +1,150 @@ +# Connection setup + +People connect an app or account, choose who may use it, and recover incomplete +setup from either Apps or a task that needs access. A saved draft, a completed +provider login, a usable connection, and a resumed task are separate checkpoints. +Chat channels additionally require an endpoint and linked sender identity. + +## Sub-features + +- `catalog`: find a provider, inspect its available methods, and open setup; + unavailable methods explain their prerequisite rather than silently switching. +- `identity-and-access`: select personal/shared identity and eligible agents; + an empty explicit selection and company-wide access must not be confused. +- `credentials`: provider sign-in, key, or generic MCP URL follows its supported + setup method; credentials are not retained in browser draft storage. +- `handoff`: provider popup/full-page callback returns to the correct setup + host with the original task intent and identity choice intact. +- `draft-recovery`: cancel, Back, Save & exit, reload, Finish setup, and reconnect + preserve the exact draft rather than creating duplicate connections. +- `task-request`: only the addressed person resolves the requested connection; + usable access releases the pending task request through normal continuation. +- `channel-setup`: provider endpoint, represented agent, linked sender, and + communication instructions are configured before an external message is used. +- `failure`: denied login, unreachable/private URL, expired credentials, and + permission errors leave an actionable state rather than a false success. + +## How to get to it (user POV) + +### `apps-catalog` + +Open Apps (`/apps`), choose an app, and connect from its landing page. Select an +available method and access, then complete setup. Existing connections open +their details; unfinished ones offer a way to finish setup. + +### `mcp-link` + +Use **Connect with a link** or `/apps/byo` for a generic MCP server. Paste its +URL, select access, and follow the probe's sign-in/key guidance. Provider-specific +catalog setup and a generic endpoint may use different flows. + +### `task-request` + +Open the task's pending connection request and its setup action as the named +user. Setup can open in a task dialog and may use an OAuth popup. Follow the +request's original link if setup falls back to a standalone page. + +### `resume-connection` + +From Apps or connection details, use Finish setup, reconnect, or the offered +authentication recovery action. Reload or return from the provider before +checking whether the same saved connection became usable. + +### `chat-channel` + +With chat connectors enabled, select a supported chat/email provider in Apps +or open `/apps/chat/connect`. Complete that provider's endpoint setup, then +open its settings (`/apps/chat/:endpointId/settings`). Follow identity linking +as the intended sender before messaging the agent externally. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). +Choose a disposable provider account/resource and record its auth method, +deployment mode, account ownership, and access selection. For live setup, use +the provider's documented prerequisites in the +[connector playbook](../doc/connections/CONNECTOR-PLAYBOOK.md). Automated fixtures +do not establish OAuth registration, public callbacks, or production provider access. + +### `apps-catalog` + +Automated: [Browse](../ui/src/pages/apps/Browse.test.tsx), +[unconnected app](../ui/src/pages/apps/AppNotConnected.test.tsx), and +[AppsConnect](../ui/src/pages/apps/AppsConnect.test.tsx) cover catalog entry, +access selection, provider-specific method choices, and setup failures with +mocked APIs. [Connection intents](../tests/e2e/connection-intents.spec.ts) +drives store and task setup against one fake provider through a useful continuation: + +```sh +pnpm exec vitest run ui/src/pages/apps/Browse.test.tsx ui/src/pages/apps/AppsConnect.test.tsx +pnpm exec playwright test -c tests/e2e/playwright.config.ts tests/e2e/connection-intents.spec.ts +``` + +Manual: connect from an unconnected provider landing. Select the intended +identity and agent access, complete authentication, reload, and inspect the +saved connection. Run a permitted read-only action with an eligible agent and +verify its useful result. Try an ineligible agent and confirm denial. Repeat +with a user who cannot install company-wide; the UI must not imply broad access. + +### `mcp-link` + +Automated: AppsConnect's generic MCP cases cover probe-driven auth, private or +unreachable endpoints, preregistered clients, secret-backed headers, and unsafe +authorization URLs. These are component/API mocks, not remote provider proof. + +Manual: connect a known test MCP URL through the link flow, verify its saved +endpoint and a read-only action, then repeat with a bad URL and wrong credential. +The error should explain the next action and preserve non-secret setup context. +Test no-auth and authenticated endpoints separately; never infer one from the other. + +### `task-request` + +Automated: [interaction card](../ui/src/components/IssueThreadInteractionCard.test.tsx) +checks addressed-user controls. AppsConnect tests cover page/dialog parity, +task-bound OAuth, popup handoff, and verifying a saved connection before closing. +The connection-intents browser suite above exercises fixture-backed continuation. + +Manual: ask an agent to use an unavailable app, open its request as the named +user, and complete setup in the dialog. Verify the card settles, the exact task +resumes, and the agent returns a useful provider result. Repeat the page-host +fallback and denied OAuth path. As another user, confirm that merely seeing the +task does not grant the right to resolve the request. + +### `resume-connection` + +Automated: AppsConnect tests cover exact-draft resume, declined OAuth, reconnect +lookup failure/retry, response-lost creation, archived connection revival, and +saved account reuse. [App detail](../ui/src/pages/apps/AppDetail.test.tsx) covers +the connection host. These tests do not complete a real provider login. + +Manual: leave setup through its footer, reload Apps, choose Finish setup, and +confirm the same connection is resumed. Decline provider login and recover from +that checkpoint. Reconnect an expired disposable account and verify a permitted +action afterwards. Count connections before/after to catch accidental duplicates. + +### `chat-channel` + +Automated: [setup routing](../ui/src/pages/apps/chat/ChatEndpointSetup.routing.test.tsx), +[saved setup state](../ui/src/pages/apps/chat/ChatEndpointSetup.state.test.ts), +[email setup](../ui/src/pages/apps/chat/EmailEndpointSetup.test.tsx), and +[identity confirmation](../ui/src/pages/apps/chat/ChatIdentityConfirm.test.tsx) +cover shared UI logic with fixtures. Provider-specific live setup is not implied. + +Manual: complete setup for one named provider, reload endpoint settings, link +the intended sender, and send a disposable message. Verify one task and a useful +reply in the originating conversation. Inspect an unlinked sender's denial and +the endpoint's pause behavior. Repeat independently for each provider at issue; +Slack setup does not qualify Discord, Telegram, GitHub, email, or iMessage. + +## Gotchas + +- A successful OAuth callback is not proof of saved connection access or task + continuation. Verify all three checkpoints. +- Personal identity, shared account access, and per-agent access are distinct. + Connecting an account does not waive an Off action or Ask first review. +- A tool app connection is not a chat endpoint. The same provider can offer both. +- Old Apps/Connections URLs can redirect to Apps. Use the current navigation and + record the actual destination rather than documenting an obsolete screen. +- Full provider matrix, AI-account selection, gateway/profile administration, + and account revocation lifecycles remain outside this seed recipe. +- For governed actions after setup, use [questions and approvals](./questions-and-approvals.md). diff --git a/feature-map/coverage.json b/feature-map/coverage.json new file mode 100644 index 0000000000..7fc99df425 --- /dev/null +++ b/feature-map/coverage.json @@ -0,0 +1,401 @@ +{ + "version": 1, + "areas": [ + { + "id": "tasks-and-attention", + "title": "Tasks, conversations, and attention", + "status": "partial", + "features": [ + "tasks.md", + "task-coordination.md", + "inbox-search.md", + "agent-chat.md", + "questions-and-approvals.md", + "steering.md", + "recovery.md", + "documents-artifacts.md" + ], + "gap": "Recipes cover the main task/conversation/attention workflows. Full shell, permission, attachment, long-thread, and concurrency permutations remain to be enumerated.", + "paths": [ + "ui/src/pages/AgentChat.tsx", + "ui/src/pages/AgentChats.tsx", + "ui/src/pages/BoardChat.tsx", + "ui/src/pages/DecisionQueuePage.tsx", + "ui/src/pages/Inbox.tsx", + "ui/src/pages/IssueDetail.tsx", + "ui/src/pages/Issues.tsx", + "ui/src/pages/LegacyInbox.tsx", + "ui/src/pages/MyIssues.tsx", + "ui/src/pages/Search.tsx", + "ui/src/pages/WhatNeedsMe.tsx" + ] + }, + { + "id": "agents", + "title": "Agents, organization, and runtime setup", + "status": "partial", + "features": [ + "agents.md", + "runs-adapters.md", + "skills.md", + "app-permissions.md", + "recovery.md", + "execution-environments.md" + ], + "gap": "Per-harness/model/account capabilities, every instruction-file error, and complete built-in-agent lifecycle variants remain separate qualification matrices.", + "paths": [ + "ui/src/pages/AdapterManager.tsx", + "ui/src/pages/AgentDetail.production.tsx", + "ui/src/pages/AgentDetail.tsx", + "ui/src/pages/AgentToolsTab.tsx", + "ui/src/pages/Agents.production.tsx", + "ui/src/pages/Agents.tsx", + "ui/src/pages/NewAgent.tsx", + "ui/src/pages/Org.tsx", + "ui/src/pages/OrgChart.production.tsx", + "ui/src/pages/OrgChart.tsx" + ] + }, + { + "id": "apps", + "title": "App catalog and connection setup", + "status": "partial", + "features": [ + "connection-setup.md", + "app-permissions.md", + "questions-and-approvals.md" + ], + "gap": "Provider-specific authentication/revocation, credential-only accounts, and aggregator administrative variants still need their own detailed matrices.", + "paths": [ + "ui/src/pages/apps/AggregatorAppManager.tsx", + "ui/src/pages/apps/AggregatorConnectDialog.tsx", + "ui/src/pages/apps/AppDetail.tsx", + "ui/src/pages/apps/AppLogo.tsx", + "ui/src/pages/apps/AppNotConnected.tsx", + "ui/src/pages/apps/AppsConnect.tsx", + "ui/src/pages/apps/AppsReview.tsx", + "ui/src/pages/apps/ArcadeDiscoverySetup.tsx", + "ui/src/pages/apps/Browse.tsx", + "ui/src/pages/apps/CatalogSourceFilters.tsx", + "ui/src/pages/apps/ComposioAppManager.tsx", + "ui/src/pages/apps/ComposioAppSetup.tsx", + "ui/src/pages/apps/ConnectionProvenanceChip.tsx", + "ui/src/pages/apps/Connections.tsx", + "ui/src/pages/apps/ExecutorManagementSetup.tsx", + "ui/src/pages/apps/PaperclipCloudOAuthHandoff.tsx", + "ui/src/pages/apps/ReviewQueueCard.tsx", + "ui/src/pages/apps/UnverifiedServerBadge.tsx", + "ui/src/pages/apps/app-detail/ActionTestDialog.tsx", + "ui/src/pages/apps/app-detail/ActivityPanel.tsx", + "ui/src/pages/apps/app-detail/AdvancedPanel.tsx", + "ui/src/pages/apps/app-detail/AgentConnectionAccess.tsx", + "ui/src/pages/apps/app-detail/BrowserUseSettingsPanel.tsx", + "ui/src/pages/apps/app-detail/ConnectedAggregatorApps.tsx", + "ui/src/pages/apps/app-detail/IdentitiesSection.tsx", + "ui/src/pages/apps/app-detail/PermissionsPanel.tsx", + "ui/src/pages/apps/app-detail/RailwayAccessPanel.tsx", + "ui/src/pages/apps/app-detail/ReviewPanel.tsx", + "ui/src/pages/apps/app-detail/SetupPanel.tsx", + "ui/src/pages/apps/connection-owner.tsx" + ] + }, + { + "id": "chat-channels", + "title": "Chat and email channel setup", + "status": "partial", + "features": [ + "chat-channels.md", + "connection-setup.md", + "questions-and-approvals.md", + "steering.md" + ], + "gap": "Shared recipes name provider checks; each provider transport/thread/identity/file-size/type combination needs separate live evidence and deeper instructions.", + "paths": [ + "ui/src/pages/apps/chat/ChatCommunicationInstructions.tsx", + "ui/src/pages/apps/chat/ChatEndpointDetail.tsx", + "ui/src/pages/apps/chat/ChatEndpointSetup.tsx", + "ui/src/pages/apps/chat/ChatIdentityConfirm.tsx", + "ui/src/pages/apps/chat/EmailEndpointSetup.tsx", + "ui/src/pages/apps/chat/GitHubBotConfiguration.tsx", + "ui/src/pages/apps/chat/GitHubBotManagement.tsx", + "ui/src/pages/apps/chat/GitHubChatSetup.tsx", + "ui/src/pages/apps/chat/GitHubSetupPrompt.tsx", + "ui/src/pages/apps/chat/PhotonConnectStep.tsx", + "ui/src/pages/apps/chat/SetupPrompt.tsx", + "ui/src/pages/apps/chat/SlackAvatarStep.tsx", + "ui/src/pages/apps/chat/SlackIdentityStep.tsx", + "ui/src/pages/apps/chat/SlackSetupPrompt.tsx", + "ui/src/pages/apps/chat/SlackToolSettings.tsx" + ] + }, + { + "id": "skills-and-teams", + "title": "Skills, Skill Studio, and teams", + "status": "partial", + "features": [ + "skills.md", + "teams.md", + "questions-and-approvals.md" + ], + "gap": "Main library/Studio/source/policy and CLI team-install paths are mapped. Full source-provider conflicts, harness sync, and remote package variants remain; catalog UI is not a current top-level route.", + "paths": [ + "ui/src/pages/CompanySkills.production.tsx", + "ui/src/pages/CompanySkills.tsx", + "ui/src/pages/SkillSources.tsx", + "ui/src/pages/SkillStudio.tsx", + "ui/src/pages/TeamCatalog.tsx", + "ui/src/pages/agent-skills/AgentSkillReleasePicker.tsx", + "ui/src/pages/agent-skills/AgentSkillRow.tsx", + "ui/src/pages/agent-skills/AgentSkillsTab.tsx", + "ui/src/pages/skills/ImportSkillsFromProjectDialog.tsx", + "ui/src/pages/skills/SkillImportProgress.tsx", + "ui/src/pages/skills/SkillPackagePreview.tsx", + "ui/src/pages/skills/SkillSourceTree.tsx" + ] + }, + { + "id": "projects-and-workspaces", + "title": "Projects and execution workspaces", + "status": "partial", + "features": [ + "projects.md", + "workspaces.md", + "goals.md", + "execution-environments.md", + "budgets-costs.md", + "recovery.md" + ], + "gap": "Provider-specific provisioning, multi-repository/submodule edge cases, Git reconciliation variants, and all service exposure combinations require deeper recipes.", + "paths": [ + "ui/src/pages/ExecutionWorkspaceDetail.tsx", + "ui/src/pages/ProjectDetail.tsx", + "ui/src/pages/ProjectWorkspaceDetail.tsx", + "ui/src/pages/Projects.tsx", + "ui/src/pages/Workspaces.tsx" + ] + }, + { + "id": "formal-approvals", + "title": "Formal governance approvals", + "status": "partial", + "features": [ + "questions-and-approvals.md", + "task-coordination.md", + "agents.md" + ], + "gap": "Formal board decisions and signoff have recipes; every approval payload/type and actor/host error permutation is not enumerated.", + "paths": [ + "ui/src/pages/ApprovalDetail.tsx", + "ui/src/pages/Approvals.tsx" + ] + }, + { + "id": "auth-and-access", + "title": "Login, invitations, and access", + "status": "partial", + "features": [ + "onboarding.md", + "access.md", + "navigation-preferences.md", + "cli-operations.md" + ], + "gap": "Deployment modes and core login/invite/member/token paths are mapped; exhaustive identity-provider, expiry, role, and resource-policy combinations remain.", + "paths": [ + "ui/src/pages/Auth.tsx", + "ui/src/pages/BoardClaim.tsx", + "ui/src/pages/CliAuth.tsx", + "ui/src/pages/CompanyAccess.tsx", + "ui/src/pages/InstanceAccess.tsx", + "ui/src/pages/InviteLanding.tsx", + "ui/src/pages/JoinRequestQueue.tsx", + "ui/src/pages/UserProfile.tsx" + ] + }, + { + "id": "company-and-instance", + "title": "Company and instance administration", + "status": "partial", + "features": [ + "companies.md", + "onboarding.md", + "instance-operations.md", + "execution-environments.md", + "navigation-preferences.md" + ], + "gap": "Core administration/import/export/operator workflows are mapped; cloud/self-hosted differences, migration/restore compatibility, and platform-specific service variants need deeper recipes.", + "paths": [ + "ui/src/pages/Companies.tsx", + "ui/src/pages/CompanyEnvironments.tsx", + "ui/src/pages/CompanyExport.tsx", + "ui/src/pages/CompanyImport.tsx", + "ui/src/pages/CompanySettings.tsx", + "ui/src/pages/InstanceExperimentalSettings.tsx", + "ui/src/pages/InstanceGeneralSettings.tsx", + "ui/src/pages/ProfileSettings.tsx" + ] + }, + { + "id": "goals-costs-and-activity", + "title": "Goals, dashboards, costs, and activity", + "status": "partial", + "features": [ + "goals.md", + "budgets-costs.md", + "activity.md", + "runs-adapters.md", + "routines.md" + ], + "gap": "Core goal/report/budget/audit journeys are mapped. Every aggregation/filter combination, cost source, and overlapping budget window still needs dedicated cases.", + "paths": [ + "ui/src/pages/Costs.production.tsx", + "ui/src/pages/Costs.tsx", + "ui/src/pages/Dashboard.tsx", + "ui/src/pages/DashboardLive.tsx", + "ui/src/pages/GoalDetail.tsx", + "ui/src/pages/Goals.tsx", + "ui/src/pages/Timeline.tsx", + "ui/src/pages/audit/AuditFeed.production.tsx", + "ui/src/pages/audit/AuditFeed.tsx", + "ui/src/pages/audit/AuditHub.tsx", + "ui/src/pages/audit/AuditRuns.tsx", + "ui/src/pages/audit/CompanyActivity.production.tsx", + "ui/src/pages/audit/CompanyActivity.tsx", + "ui/src/pages/audit/RoutineAuditActivity.tsx" + ] + }, + { + "id": "artifacts", + "title": "Artifacts and work products", + "status": "partial", + "features": [ + "documents-artifacts.md" + ], + "gap": "Document/attachment/library/work-product journeys are mapped; every media preview type, storage backend, annotation conflict, and runtime-resource lifecycle variant remains separate.", + "paths": [ + "ui/src/pages/Artifacts.tsx" + ] + }, + { + "id": "routines-and-pipelines", + "title": "Routines, pipelines, cases, and status cards", + "status": "partial", + "features": [ + "routines.md", + "pipelines.md", + "cases.md", + "status-cards.md" + ], + "gap": "All four capabilities have recipes. Trigger/provider/timezone combinations, custom case schemas, stage automation types, and summarizer quality need deeper cases.", + "paths": [ + "ui/src/pages/CaseDetail.tsx", + "ui/src/pages/Cases.tsx", + "ui/src/pages/PipelineSettings.tsx", + "ui/src/pages/Pipelines.tsx", + "ui/src/pages/RoutineDetail.production.tsx", + "ui/src/pages/RoutineDetail.tsx", + "ui/src/pages/Routines.production.tsx", + "ui/src/pages/Routines.tsx", + "ui/src/pages/StatusCards/ArchivedStatusCardRow.tsx", + "ui/src/pages/StatusCards/CreateStatusCardDialog.tsx", + "ui/src/pages/StatusCards/StatusCardDetailDrawer.tsx", + "ui/src/pages/StatusCards/StatusCardSettingsForm.tsx", + "ui/src/pages/StatusCards/StatusCardTile.tsx", + "ui/src/pages/StatusCards/SummarizerAgentSelect.tsx", + "ui/src/pages/StatusCards/index.tsx" + ] + }, + { + "id": "secrets", + "title": "Secrets and secret proposals", + "status": "partial", + "features": [ + "secrets.md", + "access.md", + "app-permissions.md" + ], + "gap": "Company/user/proposal/vault and runtime-binding paths are mapped; every secret provider, rotation scenario, and delivery context needs separate validation.", + "paths": [ + "ui/src/pages/Secrets.tsx", + "ui/src/pages/secrets/ImportFromVaultDialog.tsx", + "ui/src/pages/secrets/MissingUserSecretsBanner.tsx", + "ui/src/pages/secrets/MyUserSecretsTab.tsx", + "ui/src/pages/secrets/ProposalsTab.tsx", + "ui/src/pages/secrets/SecretPathName.tsx", + "ui/src/pages/secrets/SetMyUserSecretDialog.tsx", + "ui/src/pages/secrets/UserSecretDefinitionsTab.tsx", + "ui/src/pages/secrets/proposal-review.tsx", + "ui/src/pages/secrets/user-secret-presentation.tsx" + ] + }, + { + "id": "plugins-and-tools", + "title": "Plugins, gateways, and tool profiles", + "status": "partial", + "features": [ + "plugins.md", + "gateways-profiles.md", + "app-permissions.md", + "execution-environments.md" + ], + "gap": "Host plugin/gateway/profile lifecycles are mapped. Third-party plugin behaviors and every client transport/provider combination are outside host-wide coverage.", + "paths": [ + "ui/src/pages/CompanySettingsPluginPage.tsx", + "ui/src/pages/PluginManager.tsx", + "ui/src/pages/PluginPage.tsx", + "ui/src/pages/PluginSettings.tsx", + "ui/src/pages/apps/gateways/ConnectClientDialog.tsx", + "ui/src/pages/apps/gateways/CopyableGatewayUrl.tsx", + "ui/src/pages/apps/gateways/EditGatewayDialog.tsx", + "ui/src/pages/apps/gateways/GatewayDetail.tsx", + "ui/src/pages/apps/gateways/GatewaysList.tsx", + "ui/src/pages/apps/gateways/NewGatewayDialog.tsx", + "ui/src/pages/apps/gateways/panels/AppsToolsPanel.tsx", + "ui/src/pages/apps/gateways/panels/GatewayActivityPanel.tsx", + "ui/src/pages/apps/gateways/panels/GatewayAdvancedPanel.tsx", + "ui/src/pages/apps/gateways/panels/OverviewPanel.tsx", + "ui/src/pages/apps/gateways/panels/TokensPanel.tsx", + "ui/src/pages/tools/AdvancedToolsRoute.tsx", + "ui/src/pages/tools/AuditTab.tsx", + "ui/src/pages/tools/GatewaysTab.tsx", + "ui/src/pages/tools/McpConfigHelpDialog.tsx", + "ui/src/pages/tools/PasteConfigTab.tsx", + "ui/src/pages/tools/ProfilesTab.tsx", + "ui/src/pages/tools/SmokeLabTab.tsx", + "ui/src/pages/tools/ToolsAccess.tsx", + "ui/src/pages/tools/connection-dialogs.tsx", + "ui/src/pages/tools/profiles/ProfileActionDialog.tsx", + "ui/src/pages/tools/profiles/ProfileDetail.tsx", + "ui/src/pages/tools/profiles/ProfileDetailRoute.tsx", + "ui/src/pages/tools/profiles/ProfileWizard.tsx", + "ui/src/pages/tools/profiles/ProfileWizardRoute.tsx", + "ui/src/pages/tools/profiles/ProfilesIndex.tsx", + "ui/src/pages/tools/profiles/ToolsAdminGate.tsx", + "ui/src/pages/tools/profiles/WizardToolsStep.tsx", + "ui/src/pages/tools/shared.tsx" + ] + }, + { + "id": "labs-and-fallbacks", + "title": "Developer labs and fallback pages", + "status": "partial", + "features": [ + "developer-labs.md", + "navigation-preferences.md" + ], + "gap": "Developer and fallback surfaces are identified. Each synthetic fixture and performance budget is not a production journey and needs its own measurement.", + "paths": [ + "ui/src/pages/BootstrapSetupUxLab.tsx", + "ui/src/pages/CrossIssueCollaborationUxLab.tsx", + "ui/src/pages/DesignGuide.tsx", + "ui/src/pages/InviteUxLab.tsx", + "ui/src/pages/IssueChatLongThreadPerf.tsx", + "ui/src/pages/IssueChatUxLab.tsx", + "ui/src/pages/NotFound.tsx", + "ui/src/pages/ResponsibleUserDenialUxLab.tsx", + "ui/src/pages/RunTranscriptUxLab.tsx", + "ui/src/pages/SystemNoticeUxLab.tsx", + "ui/src/pages/TaskChatLab.tsx" + ] + } + ] +} diff --git a/feature-map/developer-labs.md b/feature-map/developer-labs.md new file mode 100644 index 0000000000..dc9a7fbec0 --- /dev/null +++ b/feature-map/developer-labs.md @@ -0,0 +1,43 @@ +# Developer previews and diagnostic labs + +Contributors can inspect design examples, interaction labs, and performance fixtures. These are development surfaces and do not count as production feature verification. + +Implementation: [route registration](../ui/src/App.tsx), [design guide](../ui/src/pages/DesignGuide.tsx), [long-thread fixture](../ui/src/pages/IssueChatLongThreadPerf.tsx). + +## Sub-features + +- `design`: inspect shared components and layout examples in the design guide or Storybook. +- `interaction-labs`: exercise synthetic bootstrap, task-chat, denial, and collaboration states. +- `performance`: measure the provided long-thread fixture with known data and environment. +- `route-gates`: distinguish dev-only, experimental, historical, and fallback surfaces. + +## How to get to it (user POV) + +### `preview-lab` + +Use `/design-guide`, registered `/ux-lab/...` routes, or Storybook; consult `ui/src/App.tsx` for the current gated set. + +### `performance-fixture` + +Open `/tests/perf/long-thread` only in an appropriate development environment. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a development/test environment. Confirm the route is registered for the current build before claiming the page is available. + +### `preview-lab` + +Automated: [onboarding variant](../ui/src/components/OnboardingWizardVariant.test.tsx) is an example component contract. There is no claim of full automated acceptance coverage for every lab page. + +Manual: Open the specific fixture state, inspect controls and layout, then repeat the affected interaction in the actual product host. Report fixture results separately from persisted task/company results. + +### `performance-fixture` + +Automated: [task thread component](../ui/src/components/IssueChatThread.test.tsx) does not establish a performance budget. Timing/scroll measurements need a dedicated browser run. + +Manual: Record browser/build/data size, exercise scrolling and composing in the fixture, and retain timing or trace evidence. Confirm a representative real task does not regress before extrapolating fixture measurements. + +## Gotchas + +- An unmounted or obsolete lab file remains in the conservative page inventory but is not a shipped entry point. +- Screenshots of a lab do not prove live provider behavior, persistence, or authorization. diff --git a/feature-map/documents-artifacts.md b/feature-map/documents-artifacts.md new file mode 100644 index 0000000000..39d96ade8b --- /dev/null +++ b/feature-map/documents-artifacts.md @@ -0,0 +1,55 @@ +# Documents, attachments, and work products + +People read and revise task documents, annotate specific content, open attached files, and inspect the outputs an agent hands back. The artifact library provides another route to the same work. + +Implementation: [task documents](../ui/src/components/IssueDocumentsSection.tsx), [artifact library](../ui/src/pages/Artifacts.tsx), [document panel](../ui/src/components/task-side-panel/TaskDocumentPanel.tsx). + +## Sub-features + +- `documents`: edit versioned task documents and inspect or restore revisions. +- `annotations`: attach feedback to document content and inspect resolution state. +- `attachments`: upload, preview, and download allowed files with company access checks. +- `work-products`: link deliverables to their source task, resource, and review context. +- `library`: search, filter, group, and open artifact stacks. + +## How to get to it (user POV) + +### `task-document` + +Open a document from the task thread or document side panel. + +### `task-output` + +Open an attachment, output card, or file link from a task. + +### `artifact-library` + +Open `/artifacts` and its grouping, search, and media controls. + +## Driving it + +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` + +Automated: [documents service](../server/src/__tests__/documents-service.test.ts), [annotations](../server/src/__tests__/document-annotations-service.test.ts), and [revision restore](../server/src/__tests__/issue-document-restore-routes.test.ts) cover server contracts. + +Manual: Edit a paragraph, save, reload, and compare revisions. Add an annotation to a specific selection and inspect it after another edit. Resolve it through the supported action. Restore a disposable revision and confirm the new current document and history agree. + +### `task-output` + +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 the arrival experience. + +Manual: Upload a fixture and have the test task produce an output. Preview and download each, compare the contents, and follow the source task link. Reload and test an inaccessible user/company; verify missing workspace-only resources have an explicit state. + +### `artifact-library` + +Automated: [artifact page](../ui/src/pages/Artifacts.test.tsx) covers grouping, search requests, and pagination using mocks. + +Manual: Find the task’s output through search and grouping, open its stack, page through results, and reload a direct stack link. Confirm the same file/content appears as from the task. + +## Gotchas + +- 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. diff --git a/feature-map/execution-environments.md b/feature-map/execution-environments.md new file mode 100644 index 0000000000..feb89f353d --- /dev/null +++ b/feature-map/execution-environments.md @@ -0,0 +1,45 @@ +# Local, SSH, and sandbox environments + +Operators configure where agents execute, probe readiness, select an environment for work, and inspect remote provisioning or custom-image state when the installed provider supports it. + +Implementation: [environment settings](../ui/src/pages/CompanyEnvironments.tsx), [environment runtime](../server/src/services/environment-runtime.ts). + +## Sub-features + +- `configuration`: inspect local environments and configure available SSH/sandbox targets. +- `capabilities`: select only drivers/providers that advertise the required execution capability. +- `probe`: test reachability and runtime prerequisites in the actual target. +- `assignment`: bind the intended agent/project/workspace to its execution target. +- `images`: inspect supported sandbox custom-image preparation and terminal workflows. + +## How to get to it (user POV) + +### `environment-settings` + +Open Settings → Environments, then create/edit a supported target. + +### `remote-execution` + +Choose the environment in agent/project/workspace configuration, then inspect the resulting task/run and workspace. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use an owned disposable target and a supported provider plugin. Record provider, target identity, account, and spending constraints before a live remote run. + +### `environment-settings` + +Automated: [environment UI](../ui/src/pages/CompanyEnvironments.test.tsx), [driver configuration UI](../ui/src/pages/CompanySettings.test.tsx), and [environment service](../server/src/__tests__/environment-service.test.ts) cover configuration behavior. + +Manual: Save a disposable target, reload it, and run its available probe. Verify both success and missing-credential/reachability errors identify the target. Confirm unavailable providers are not offered as working run targets. + +### `remote-execution` + +Automated: [execution target](../server/src/__tests__/environment-execution-target.test.ts) and [custom images](../server/src/__tests__/environment-custom-images-service.test.ts) cover contracts; [SSH live test](../server/src/__tests__/environment-live-ssh.test.ts) requires its own external setup. + +Manual: Run a bounded command in the intended target, inspect its output and workspace, and verify execution did not silently fall back to the server host. For custom-image changes, build/probe the disposable image before assigning it. Inspect cleanup and shutdown after the run. + +## Gotchas + +- A probe is narrower evidence than a complete task with tools, files, and resumption. +- The local option may appear only when editing an existing local environment; availability follows current UI/provider capabilities. +- Workspace service reachability and environment reachability are separate checks. diff --git a/feature-map/gateways-profiles.md b/feature-map/gateways-profiles.md new file mode 100644 index 0000000000..616c73d8c3 --- /dev/null +++ b/feature-map/gateways-profiles.md @@ -0,0 +1,45 @@ +# Tool gateways and access profiles + +Administrators expose selected tools through gateways and reusable access profiles, connect clients, manage tokens, and inspect gateway activity. + +Implementation: [gateways](../ui/src/pages/apps/gateways/GatewaysList.tsx), [gateway detail](../ui/src/pages/apps/gateways/GatewayDetail.tsx), [profiles](../ui/src/pages/tools/profiles/ProfileWizard.tsx). + +## Sub-features + +- `gateway`: create/edit an endpoint and select its exposed apps/tools. +- `profiles`: define reusable tool access configuration and inspect draft/detail state. +- `client-connect`: copy the intended endpoint/configuration to an authorized test client. +- `tokens`: create/revoke client credentials and verify their scope. +- `activity`: inspect tool discovery/calls and explicit errors. + +## How to get to it (user POV) + +### `gateway-client` + +Open `/apps/gateways`, then a gateway’s Overview, Apps/Tools, Tokens, and Activity tabs. + +### `access-profile` + +Open `/apps/advanced/profiles`, create a profile, or follow its detail/edit route. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a fixture tool connection and test client. Record gateway/profile, token owner, transport, and selected company. + +### `gateway-client` + +Automated: [gateway service](../server/src/__tests__/tool-gateway-service.test.ts), [connect client dialog](../ui/src/pages/apps/gateways/ConnectClientDialog.test.tsx), and [token panel](../ui/src/pages/apps/gateways/panels/TokensPanel.test.tsx) cover service/UI contracts. + +Manual: Create a disposable gateway with one harmless tool, connect a client using its provided configuration, discover/call that tool, and inspect activity. Revoke the client token and confirm the same call fails. Test a tool outside the allowed set. + +### `access-profile` + +Automated: [profile wizard](../ui/src/pages/tools/profiles/ProfileWizard.test.tsx) and [profile detail](../ui/src/pages/tools/profiles/ProfileDetail.test.tsx) cover component behavior with mocks. + +Manual: Create a bounded profile, choose its offered tools and options, save or resume its draft, and reload the detail. Apply/connect it through the offered flow and inspect the actual client-visible tool set. Verify cancellation and invalid selections retain an understandable draft. + +## Gotchas + +- A copied endpoint is not proof of client authentication or tool discovery. +- Gateway access cannot replace underlying connection/action permission checks. +- Advanced tool routes require the appropriate admin gate; legacy tool URLs may redirect. diff --git a/feature-map/goals.md b/feature-map/goals.md new file mode 100644 index 0000000000..a282d35345 --- /dev/null +++ b/feature-map/goals.md @@ -0,0 +1,42 @@ +# Goals and work alignment + +People define company and lower-level goals and connect projects and tasks to the outcome they serve. + +Implementation: [goals](../ui/src/pages/Goals.tsx), [goal detail](../ui/src/pages/GoalDetail.tsx). + +## Sub-features + +- `hierarchy`: create and inspect goal level, parent, owner, and status. +- `alignment`: associate work with a valid goal in the same company. +- `navigation`: follow goal/project/task context to understand why work exists. + +## How to get to it (user POV) + +### `goal-detail` + +Open `/goals`, create a goal, and enter `/goals/:goalId`. + +### `task-goal-context` + +Inspect the goal context from a project or task and compare explicit versus inherited context. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Prepare two goals and a disposable project/task in the selected company. + +### `goal-detail` + +Automated: [project-goal validation](../server/src/__tests__/project-goal-validation.test.ts) covers relationship validation; [goal detail control](../ui/src/pages/GoalDetail.test.tsx) only tests the properties toggle, not the whole creation journey. + +Manual: Create a parent and child goal, save owner/status changes, and reload. Link a project and task through the offered controls, follow their goal context, and verify a cross-company or invalid relationship is rejected. + +### `task-goal-context` + +Automated: [task goal routes](../server/src/__tests__/issues-goal-context-routes.test.ts) and [goal fallback](../server/src/__tests__/issue-goal-fallback.test.ts) cover the server rules. + +Manual: Compare a task with an explicit goal to one relying on project context. Change the allowed association, reload, and verify the displayed/injected context follows the documented server rule rather than retaining an unrelated goal. + +## Gotchas + +- A goal status is not an independently measured proof of business success. +- Do not infer a complete goal browser test from the small properties-toggle suite. diff --git a/feature-map/inbox-search.md b/feature-map/inbox-search.md new file mode 100644 index 0000000000..2ef31ac7c7 --- /dev/null +++ b/feature-map/inbox-search.md @@ -0,0 +1,54 @@ +# Inbox, decisions, and search + +People find work that needs their attention, distinguish unread activity from required decisions, archive handled items, and search across the company. + +Implementation: [inbox](../ui/src/pages/Inbox.tsx), [decisions](../ui/src/pages/WhatNeedsMe.tsx), [search](../ui/src/pages/Search.tsx). + +## Sub-features + +- `views`: use Mine, Recent, Unread, Blocked, and broader task views. +- `triage`: read or archive attention items without pretending the underlying task is complete. +- `decisions`: open the source of a decision and act in the right context. +- `search`: query company work and follow a result to its original record. + +## How to get to it (user POV) + +### `inbox` + +Use Inbox links or the corresponding task views when the combined list is enabled. + +### `decisions` + +Open `/decisions`, then a queue at `/decisions/queues/:key` and its source item. + +### `search` + +Open `/search` or the navigation search entry. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Seed assigned, unread, blocked, and resolved tasks plus a pending decision. Record the combined Inbox/Tasks experimental setting. + +### `inbox` + +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. + +Manual: Read an unread task, return to Unread, archive a handled item, and reload. Verify personal triage state changes while task status stays correct. Switch users and companies to check isolation. + +### `decisions` + +Automated: [decision queues](../server/src/__tests__/decision-queues-routes.test.ts) covers route behavior. End-to-end queue-to-source navigation is manual. + +Manual: Open a pending decision, follow its source, resolve it through the supported control, and reload the queue. Confirm it retires only after the decision persisted and unrelated pending items remain. + +### `search` + +Automated: [search page](../ui/src/pages/Search.test.tsx) and [company search service](../server/src/__tests__/company-search-service.test.ts) cover UI and server search separately. + +Manual: Search a unique task title and content phrase, open the result, and compare the actual record. Test filters, no results, and a second company. Verify stale results do not expose inaccessible data. + +## Gotchas + +- Personal archival is not task cancellation or completion. +- Legacy Inbox routes can redirect to the combined task view; record which host actually rendered. +- Search service tests do not establish the relevance quality of every query. diff --git a/feature-map/instance-operations.md b/feature-map/instance-operations.md new file mode 100644 index 0000000000..dbed223088 --- /dev/null +++ b/feature-map/instance-operations.md @@ -0,0 +1,45 @@ +# Installation, configuration, updates, and backups + +An operator can install and run Paperclip, diagnose the instance, configure supported deployment settings, manage its service, and produce a recoverable database backup. + +Implementation: [CLI entry point](../cli/src/index.ts), [instance settings](../ui/src/pages/InstanceExperimentalSettings.tsx), [backup command](../cli/src/commands/db-backup.ts). + +## Sub-features + +- `install-update`: inspect install channel/version and apply supported update or rollback operations. +- `server-service`: start/stop the intended instance and inspect its service health. +- `configuration`: configure database, server binding, storage, secrets, and available experimental settings. +- `diagnostics`: use doctor/health output to distinguish readiness from a listening port. +- `backup`: create and inspect backups and verify restore only into a separate disposable target. + +## How to get to it (user POV) + +### `operator-cli` + +Use `paperclipai install`, `run`, `service`, `doctor`, `configure`, `channels`, or `update --help` for the intended operation. + +### `settings-backup` + +Use currently visible instance settings for experiments/access and `paperclipai db:backup --help` for one-off backup. Some legacy general-settings URLs redirect. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a disposable data directory/service identity. Do not update, restart, or restore over an unrelated live instance as a documentation test. + +### `operator-cli` + +Automated: [doctor](../cli/src/__tests__/doctor.test.ts), [update command](../cli/src/__tests__/update-command.test.ts), and [service manager](../cli/src/__tests__/service-manager.test.ts) cover command contracts. + +Manual: Inspect the selected installation/channel and configuration, start the isolated instance, confirm health and browser access, then stop that instance. For update changes, use the dry-run/check path first and verify installed version and rollback state on an owned disposable installation. + +### `settings-backup` + +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. + +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. + +## Gotchas + +- A successful backup write does not prove restoration works. +- Settings visibility and mutability differ for cloud-managed and self-hosted instances. +- Keep the three data paths distinct: first-party Telemetry, operator-configured OpenTelemetry, and local run logs. diff --git a/feature-map/navigation-preferences.md b/feature-map/navigation-preferences.md new file mode 100644 index 0000000000..66794028f8 --- /dev/null +++ b/feature-map/navigation-preferences.md @@ -0,0 +1,45 @@ +# Navigation, profile, and announcements + +People organize their sidebar, move between company resources, maintain their profile, and dismiss product announcements with the correct persistence and identity scope. + +Implementation: [sidebar](../ui/src/components/Sidebar.tsx), [profile](../ui/src/pages/ProfileSettings.tsx), [announcements](../ui/src/components/AnnouncementWell.tsx). + +## Sub-features + +- `navigation`: use current sidebar links, favorites, recents, and available layout controls. +- `preferences`: persist supported ordering/collapse choices for the intended user/company. +- `profile`: edit personal identity and inspect public profile links. +- `announcements`: inspect and dismiss an announcement with its intended instance-wide user scope. +- `fallbacks`: handle missing resources and old deep links without presenting another resource as the target. + +## How to get to it (user POV) + +### `sidebar-deep-links` + +Use starred/recent/sidebar links and direct company-prefixed URLs. + +### `profile-announcements` + +Use Settings → Profile, `/u/:userSlug`, and the announcement well when a publication is available. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use two test users and companies; record the selected UI shell and any client-local preference storage. + +### `sidebar-deep-links` + +Automated: [sidebar](../ui/src/components/Sidebar.test.tsx) and [sidebar preference routes](../server/src/__tests__/sidebar-preferences-routes.test.ts) cover UI/server behavior. + +Manual: Star and reorder supported resources, collapse a section, navigate and reload. Switch company/user and inspect the intended preference scope. Open an unavailable resource and a legacy route; verify clear fallback or correct redirect without leaking another company’s state. + +### `profile-announcements` + +Automated: [profile page](../ui/src/pages/ProfileSettings.test.tsx), [announcement hook](../ui/src/hooks/useAnnouncement.test.tsx), and [announcement routes](../server/src/__tests__/announcements-routes.test.ts) cover separate UI/persistence layers. + +Manual: Change a disposable user’s display details, reload, and inspect an attributed profile link. Dismiss a fixture announcement, switch companies, and verify it remains dismissed for that user; check another user still has their own dismissal state. + +## Gotchas + +- Announcement dismissals are intentionally instance-wide user preferences, unlike company-scoped domain data. +- Legacy/production shells need their own navigation check when affected. +- A route redirect is part of the journey; do not document a removed screen as if it still renders. diff --git a/feature-map/onboarding.md b/feature-map/onboarding.md new file mode 100644 index 0000000000..4a47e0a9fd --- /dev/null +++ b/feature-map/onboarding.md @@ -0,0 +1,45 @@ +# Onboarding and first work + +An operator can start an instance, create a company, configure its first agent, and reach a real first task. Instance setup and company onboarding are separate steps. + +Implementation: [web wizard](../ui/src/components/OnboardingWizard.tsx), [CLI setup](../cli/src/commands/onboard.ts). + +## Sub-features + +- `instance`: choose local instance configuration and start the server. +- `company`: create a company with its identity and initial agent. +- `adapter`: choose an available harness, model, account, and execution environment. +- `first-task`: leave setup with a task whose execution or missing prerequisite is visible. +- `resume`: return to an incomplete wizard without losing saved state. + +## How to get to it (user POV) + +### `web-wizard` + +Open `/onboarding` or the onboarding launcher in an empty company context. + +### `cli-setup` + +Use `paperclipai onboard --help` or `paperclipai run --help` to select an isolated data directory before setup. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a new isolated data directory and record deployment mode. A configured adapter may still need account authentication. + +### `web-wizard` + +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. + +Manual: Create a disposable company and first agent. Save and leave midway, reopen, and finish. Follow the created first task, verify the selected agent and company, and inspect its output or explicit authentication gate. Reload both company and task. + +### `cli-setup` + +Automated: [CLI onboarding](../cli/src/__tests__/onboard.test.ts) and [isolated test drive](../cli/src/__tests__/test-drive.test.ts) cover their setup contracts; they do not establish that every model account is usable. + +Manual: Run setup in the disposable directory, open the URL it prints, and confirm the instance identity and company. Restart using that same configuration and verify saved state. Exercise an unavailable adapter and confirm an actionable error. + +## Gotchas + +- An empty company, an empty instance, and an unauthenticated browser are different states. +- Creating an agent does not prove its provider login or first execution succeeded. +- See [access](./access.md) for authenticated deployments and [agents](./agents.md) for later hiring. diff --git a/feature-map/pipelines.md b/feature-map/pipelines.md new file mode 100644 index 0000000000..ac0bd5d48b --- /dev/null +++ b/feature-map/pipelines.md @@ -0,0 +1,44 @@ +# Pipelines, review queues, and learnings + +With the pipeline experiment enabled, people move structured work through configured stages, inspect stage automation, review outputs, and retain learning records. + +Implementation: [pipeline board and item hosts](../ui/src/pages/Pipelines.tsx), [pipeline configuration](../ui/src/pages/PipelineSettings.tsx). + +## Sub-features + +- `stages`: configure stage order, behavior, and automation assignees. +- `items`: create or inspect items, grouping, stage state, and work references. +- `review`: act on the pipeline review queue and inspect the resulting transition. +- `learnings`: inspect the separate learning view and its source context. + +## How to get to it (user POV) + +### `pipeline-board` + +Open `/pipelines`, `/pipelines/:pipelineId`, and its Settings route. + +### `item-review-learning` + +Open `/pipelines/:pipelineId/items/:caseId`, `/review-queue`, or `/learnings`. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enable pipelines and prepare a disposable pipeline with at least two stages and a fixture agent. Record any associated case type. + +### `pipeline-board` + +Automated: [pipeline UI helpers](../ui/src/pages/Pipelines.test.tsx) cover grouping and presentation helpers; [pipeline service](../server/src/__tests__/pipelines-service.test.ts) covers service behavior. + +Manual: Configure stages and a harmless automation, add an item, and inspect its stage. Follow its task/work references and observe the resulting transition. Reload grouping and settings; verify rejected or failed transitions leave the item in an intelligible state. + +### `item-review-learning` + +Automated: [pipeline tutorial browser suite](../tests/e2e/pipelines-tutorial-flow.spec.ts) targets a fixture journey; it does not qualify arbitrary stage automation or learning quality. + +Manual: Open a pending review, inspect its source output and revision, accept or reject, and verify the persisted stage outcome. Follow a learning record to its source context and confirm it belongs to the intended pipeline/company. + +## Gotchas + +- These routes are experimental and may redirect or deny access when disabled. +- ReviewQueue and Learnings are hosted from the pipeline module; a page-file inventory alone misses them. +- Pipeline items and free-standing [cases](./cases.md) share records but have different navigation contexts. diff --git a/feature-map/plugins.md b/feature-map/plugins.md new file mode 100644 index 0000000000..b97f79758e --- /dev/null +++ b/feature-map/plugins.md @@ -0,0 +1,44 @@ +# Plugins and contributed product surfaces + +Operators install and configure plugins, inspect their status and errors, and use their contributed pages, tools, and managed resources within the plugin’s granted capabilities. + +Implementation: [plugin manager](../ui/src/pages/PluginManager.tsx), [plugin settings](../ui/src/pages/PluginSettings.tsx), [plugin page](../ui/src/pages/PluginPage.tsx). + +## Sub-features + +- `installation`: install a trusted test package or local development plugin through supported controls. +- `configuration`: save validated configuration and inspect activation/failure state. +- `contributions`: open plugin routes, settings, tools, and contributed resource tabs. +- `lifecycle`: disable/remove or reload a disposable plugin and observe cleanup. + +## How to get to it (user POV) + +### `plugin-administration` + +Open Settings → Plugins where permitted, or the CLI plugin commands. + +### `plugin-contribution` + +Open `/plugins/:pluginId`, a registered plugin route, or its contributed company/project settings surface. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a known local fixture plugin with bounded capabilities. Record installed version and any declared external dependencies. + +### `plugin-administration` + +Automated: [install authorization](../server/src/__tests__/plugin-install-route-security.test.ts) and [plugin settings](../ui/src/pages/PluginSettings.test.tsx) cover route/UI contracts. + +Manual: Install the fixture, supply its configuration, activate it, and inspect status. Save an invalid configuration and verify a useful error. Disable/remove the disposable plugin and check its tools and managed resources no longer behave as active. + +### `plugin-contribution` + +Automated: [static plugin UI](../server/src/__tests__/plugin-ui-static.test.ts) and [company settings contribution](../ui/src/pages/CompanySettingsPluginPage.test.tsx) cover serving/host behavior. + +Manual: Open the contributed page by navigation and cold deep link, perform a harmless plugin action, and inspect its real outcome. Switch company and test an actor without the capability. Reload with the plugin unavailable and verify the host reports that state. + +## Gotchas + +- Installing a plugin does not authorize every host capability or external action. +- Plugin-provided routes are dynamic; this map covers the host lifecycle, not every third-party feature. +- Environment-driver plugins also need the [environment](./execution-environments.md) checks. diff --git a/feature-map/projects.md b/feature-map/projects.md new file mode 100644 index 0000000000..f2c7f45591 --- /dev/null +++ b/feature-map/projects.md @@ -0,0 +1,44 @@ +# Projects and repositories + +People group tasks into projects, attach goals and repositories, and configure the context and defaults used by project work. + +Implementation: [project list](../ui/src/pages/Projects.tsx), [project detail](../ui/src/pages/ProjectDetail.tsx). + +## Sub-features + +- `lifecycle`: create, name, organize, and archive projects. +- `task-context`: inspect project tasks and create work in the selected project. +- `repositories`: configure repository/workspace sources and verify usable checkouts. +- `defaults`: maintain project instructions, environment, goal, and budget context where offered. + +## How to get to it (user POV) + +### `project-list` + +Open `/projects`, create a project, and enter its overview or Issues view. + +### `repository-settings` + +Open `/projects/:projectId/configuration` and its repository/workspace settings. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a disposable project and a small repository you can access; record checkout and credential ownership. + +### `project-list` + +Automated: [projects UI](../ui/src/pages/Projects.test.tsx) and [project detail](../ui/src/pages/ProjectDetail.test.tsx) are component tests. + +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` + +Automated: [repository persistence](../server/src/__tests__/project-repositories-persistence.test.ts) and [repository browser suite](../tests/e2e/project-repositories.spec.ts) cover configured repository workflows. + +Manual: Attach a small repository, save, and create a project task. Inspect the actual checkout/revision used by its run. Test an invalid repository and missing credentials without treating a saved URL as a working workspace. + +## Gotchas + +- Project repository configuration and a provisioned execution workspace are different records. +- See [workspaces](./workspaces.md), [goals](./goals.md), and [budgets](./budgets-costs.md) for those features. +- Do not assume a deleted or archived project should erase its historical task evidence. diff --git a/feature-map/questions-and-approvals.md b/feature-map/questions-and-approvals.md new file mode 100644 index 0000000000..0446cd11c3 --- /dev/null +++ b/feature-map/questions-and-approvals.md @@ -0,0 +1,182 @@ +# Questions and approvals + +People answer an agent's questions and decide requests without losing the task's +history. A question, plan confirmation, governance approval, and app-tool review +can look similar but have different authority and continuation rules. Each +decision must stay attached to its original request and survive reload. + +## Sub-features + +- `questions`: single-choice, multiple-choice, custom, and free-text answers; + paged forms retain answers until submission and show validation failures. +- `dismiss-and-reopen`: unanswered questions remain in the feed after dismissal + or a newer message; reopening restores the form without inventing an answer. +- `confirmations`: accept, decline, or request changes; stale, expired, resolved, + and withdrawn requests cannot be acted on again. +- `plan-review`: inspect the requested plan revision before accepting or asking + for changes. An ordinary planning task can proceed to execution; Agent Chat + hands work to linked tasks and remains a conversation. +- `audience`: the current actor, company, named audience, and review policy govern + resolution. A visible request is not necessarily actionable by that viewer. +- `governance`: pending/history views, approve/reject, revision request, and + resubmission for formal board approvals. +- `tool-review`: approve once, always allow the displayed scope, or decline; + decision status and provider execution outcome remain distinct. +- `continuation`: one recorded response leads to the eligible waiting run or + continuation; repeated clicks, reloads, and competing tabs do not repeat work. + +## How to get to it (user POV) + +### `task-thread` + +Open a task from Tasks, search, a project, or its direct `/issues/:issueId` link. +Answer the question near the composer, or reopen its compact unanswered entry +in the history. Open the plan preview before using the confirmation controls. +Exercise both available task presentations when a change affects shared cards. + +### `agent-chat` + +With Agent Chat enabled, choose Chat and an agent (`/chats/:agentRef`). Answer, +dismiss, or reopen requests in this persistent conversation. A plan handoff here +creates linked work rather than turning the conversation into implementation. + +### `attention` + +Open Decisions (`/decisions`, including a saved queue) or an Inbox attention row. +Expand an actionable interaction inline; follow its task link to inspect context. +With combined Inbox/Tasks enabled, open the corresponding Tasks view instead. + +### `board-approval` + +Open Approvals → Pending or All (`/approvals/pending`, `/approvals/all`). Use the +card action or open `/approvals/:approvalId` for details, comments, revision +request, and resubmission. These are formal approvals, not ordinary questions. + +### `app-review` + +In a task, open **Review request** for an Ask first app call. The same request +appears in Apps → Review (`/apps/review`) and the connection's Review tab. +Use **Approve & run**, **Always allow**, or **Decline** on the surface under test. + +### `skill-test` + +Open Skill Studio, run a skill test that produces an interaction, and inspect +its output card. Skill-test authority is narrower than an ordinary company run. + +### `external-channel` + +In a configured chat channel, answer a published question or confirmation as a +linked sender. Open the associated Paperclip task to inspect the saved outcome. +Channel-specific forms and identity linking require separate provider evidence. + +## Driving it + +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; +a component fixture alone cannot prove live response delivery. + +### `task-thread` + +Automated: [interaction cards](../ui/src/components/IssueThreadInteractionCard.test.tsx), +[paged task cards](../ui/src/components/task-chat/TaskChatInteractionCard.test.tsx), +and [task thread](../ui/src/components/TaskChatThread.test.tsx) cover form, +receipt, and dismissal behavior. [Resolution routes](../server/src/__tests__/issue-thread-interaction-routes.test.ts) +and [response delivery](../server/src/__tests__/question-response-delivery.test.ts) +cover authority and durable continuation. Run a targeted set with: + +```sh +pnpm exec vitest run ui/src/components/TaskChatThread.test.tsx server/src/__tests__/question-response-delivery.test.ts +``` + +Manual: answer a multi-page question, go back, edit, then submit. Reload and +confirm the saved answers and one agent continuation. On a fresh request, +dismiss, reload, reopen, and verify the draft. Send a new comment while a +question remains unanswered; it must stay reopenable in history. Try a denied +actor and a request already resolved in another tab; expect an explicit error +or settled receipt, never a second decision. For plans, change the plan revision +before trying the old approval, then review the current revision. + +### `agent-chat` + +Automated: the [task thread suite](../ui/src/components/TaskChatThread.test.tsx) +parameterizes unanswered-question history for conversation mode on and off. +This proves component parity, not a model's plan handoff. + +Manual: repeat dismissal, reload, reopening, and answer submission in Chat. +Approve a plan and inspect the linked execution task and copied plan. The chat +history remains and the conversation does not close as a completed task. + +### `attention` + +Automated: [attention resolver](../ui/src/components/AttentionInteractionResolver.test.tsx) +covers preparing-request refresh without accepting it. The resolution-route +tests above cover the API, not every Decisions or Inbox navigation path. + +Manual: open the same pending request in an attention row and task tab. Resolve +from the row; both surfaces must settle after refresh. Check an empty queue, +loading, permission denial, and a stale request. Repeat with combined Inbox/Tasks +on when that surface is part of the change. Full navigation parity remains a +manual coverage gap. + +### `board-approval` + +Automated: [approval service](../server/src/__tests__/approvals-service.test.ts) +and [idempotency routes](../server/src/__tests__/approval-routes-idempotency.test.ts) +cover persistence and duplicate decisions. They do not drive the approval pages. + +Manual: create disposable formal approval requests; approve one from the list, +reject another from details, and request revision on a third. Resubmit that +third request and verify Pending/All and detail history after reload. Confirm +the recorded decision and its governed effect, not just a success toast. + +### `app-review` + +Automated: [connection reviews](../tests/e2e/connection-reviews.spec.ts) drives +task/queue synchronization, approve, decline, remembered permission, provider +failure, and restart with a scripted process agent and local MCP provider: + +```sh +pnpm exec playwright test -c tests/e2e/connection-reviews.config.ts +``` + +Manual: dismiss and reopen a review, decide it from each entry point using fresh +requests, and inspect the continuation's useful result. Always allow must show +its scope; a future action with changed arguments should obey the saved rule. +Provider failure must remain an approved decision with a failed execution. +Real provider and model checks follow [Task reviews](../doc/connections/TASK-REVIEWS.md#verification-workflows). + +### `skill-test` + +Automated: [read-only interaction contract](../server/src/__tests__/issue-interactions-read-only-contract.test.ts) +checks that fetching interactions does not mutate them. Shared card suites cover +rendering. Neither proves the complete Skill Studio host or its permission matrix. + +Manual: run a skill test with a question, answer through its visible output, +and inspect the test result. Attempt a governed action outside the test's scope; +expect denial. The complete Skill Studio browser journey is not covered by the +referenced unit tests. + +### `external-channel` + +Automated: [chat question forms](../server/src/services/chat-question-forms.test.ts), +[Discord forms](../server/src/services/chat-discord-question-forms.test.ts), +and [interaction publications](../server/src/__tests__/chat-interaction-publications.test.ts) +cover serialization and delivery logic with fixtures. + +Manual: use a disposable provider conversation, answer as the linked sender, +and check the task's persisted result and one continuation. Repeat from an +unlinked or wrong sender and with an expired card. A browser answer does not +qualify Slack, Discord, Telegram, email, or iMessage; record each as not run +unless its actual provider journey was driven. + +## Gotchas + +- 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. +- Do not reuse an accepted request to test rejection; use another request. +- Agent Chat and skill tests have distinct lifecycle/authority rules despite + sharing UI. A watchdog cannot acquire board authority by resolving a card. +- An answer to an old question can queue behind a successor run; it does not + automatically steer that run. See [steering](./steering.md). diff --git a/feature-map/recovery.md b/feature-map/recovery.md new file mode 100644 index 0000000000..3e8a856467 --- /dev/null +++ b/feature-map/recovery.md @@ -0,0 +1,159 @@ +# Recovery + +People can see why a task stopped, who owns the next action, and whether a safe +continuation is available. Recovery retains task context and ownership, honors +pause and budget gates, and distinguishes confirmed failure from an uncertain +external outcome. A retry acknowledgement alone is not proof that work resumed. + +## Sub-features + +- `diagnosis`: a task/run exposes the recorded cause, evidence, owner, attempt + progress, and next action without requiring a raw-log interpretation. +- `bounded-continuation`: supported interrupted work continues with preserved + conversation context and bounded attempts, without blindly replaying tools. +- `source-action`: source-scoped recovery actions remain attached to the task; + independent repair work may have its own issue and return owner. +- `exhaustion`: exhausted or overdue recovery exposes the current gate and + permitted operator action; it does not claim an automatic path is still live. +- `workspace`: workspace divergence/export failures show the applicable repair, + reconcile, or isolated reissue action with evidence and authority checks. +- `unknown-outcome`: uncertain external side effects require inspection and + an explicit decision, not automatic replay. +- `user-continuation`: saved user messages after a stop are reconsidered once + cleanup proves the old execution is stopped; duplicate wakes are avoided. +- `reconnect`: browser stream recovery refreshes persisted state without claiming + the agent itself restarted or that a failed run succeeded. + +## How to get to it (user POV) + +### `source-task` + +Open the affected task from Tasks, Inbox/Blocked, search, or a direct task link. +Inspect the recovery notice/card in its history, expand details if needed, and +use the currently offered action. Follow any linked repair task and return owner. + +### `run-detail` + +Open the agent's run (`/agents/:agentId/runs/:runId`) from activity or the task's +run link. The run page hosts workspace recovery controls only for a failed run +with error code `workspace_validation_failed` and a linked source task that still +has a live `workspace_validation` recovery action. Use the source task for other +stopped-run recovery checks. + +### `operator-retry` + +On an exhausted disposition or workspace recovery card, inspect the current +reason and use the permitted retry/repair/reconcile action. Some repairs require +confirmation; unavailable actions must explain the gate or remain absent. + +### `post-stop-message` + +After a stop, send a new instruction on the same task or inspect one already +saved while cleanup was pending. Observe the waiting message, continuation, and +eventual result rather than manually changing the task status to look complete. + +### `browser-reconnect` + +While viewing an active or recovering task, interrupt the browser connection +and restore it, or suspend and return to the tab. Reload is a separate check. +The current task and run state should reconcile with the server. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). +Use a disposable instance and reproducible failure. Record source task/run, +adapter/runtime mode, cause, attempt count, current owner, and verified stop +evidence. Do not kill an unrelated server or induce provider side effects just +to get a failure screen. Use the existing deterministic recovery suite first. + +### `source-task` + +Automated: [recovery actions](../server/src/__tests__/issue-recovery-actions.test.ts) +covers source scoping, bounded attempts, operator stops, quota monitoring, +ownership, stale action retirement, and continuation deduplication. +[Recovery cards](../ui/src/components/IssueRecoveryActionCard.test.tsx) cover +diagnosis, retry progress, exhaustion, and action availability. The fixture-backed +[execution-recovery journeys](../tests/e2e/execution-recovery/recovery.spec.ts) +start their own test-drive instances and exercise safe, uncertain, restart, +manager-lineage, and legacy-unknown paths: + +```sh +pnpm exec vitest run server/src/__tests__/issue-recovery-actions.test.ts ui/src/components/IssueRecoveryActionCard.test.tsx +pnpm exec playwright test -c tests/e2e/execution-recovery/playwright.config.ts recovery.spec.ts +``` + +Manual: open a stopped task through each affected navigation path. Confirm its +explanation, original owner, recovery owner if different, and next action. Follow +the supported recovery until the source task produces a useful result or a +specific escalation. Reload and verify that resolved notices retire and attempt +history remains. A fixture pass does not qualify every live harness/provider. + +### `run-detail` + +Automated: [run workspace recovery](../ui/src/components/RunWorkspaceRecoverySurface.test.tsx) +tests this host; it is component coverage, not an end-to-end repair. + +Manual: prepare a failed run with error code `workspace_validation_failed`, a +linked source task, and a live `workspace_validation` recovery action on that +task. Open that exact run and compare its recovery diagnosis to the source task. +Use an eligible action from the run surface, return to the task, +and verify the same action state, persisted outcome, and restored execution. +Repeat with an actor who lacks authority. Verify that the run-page controls are +absent for other error codes or after the source action retires; continue other +recovery checks on the source task. Full run-detail navigation remains a manual +gap. + +### `operator-retry` + +Automated: [disposition notices](../ui/src/components/DispositionRecoveryNotice.test.tsx) +tests pending/error/gated states and waiting for the real retry acknowledgement. +The recovery-card suite covers workspace divergence, reissue, reconcile, and +confirmation. [Workspace export](../ui/src/components/WorkspaceExportRecovery.test.tsx) +covers its separate repair surface. + +Manual: reproduce an exhausted disposable action. Click once, verify pending +state prevents repeated clicks, and inspect a successful continuation or an +explicit rejection. Reload to confirm the durable outcome. For a workspace +repair, record the compared branches/revisions and preserve uncommitted work; +confirm the repair's actual result before resuming. Check the denied and stale +action paths. A changed card label is insufficient proof of workspace integrity. + +### `post-stop-message` + +Automated: [legacy continuation](../server/src/services/recovery/legacy-continuation.test.ts), +[queue routes](../server/src/__tests__/issue-queued-comments-routes.test.ts), and +[native restart recovery](../server/src/services/native-runtime/native-restart-recovery.test.ts) +cover their respective recovery paths. [Legacy failure continuation](../tests/e2e/legacy-failure-continuation.spec.ts) +adds a browser journey; it is not native runtime proof. + +Manual: stop a disposable run, submit a distinguishable follow-up, and observe +any cleanup wait. After confirmed stop, verify the follow-up reaches one eligible +continuation and produces the requested answer. Repeat with a task/ancestor +pause and a budget hold: recovery must not bypass the gate. For unknown external +outcomes, inspect the provider before authorizing another operation. + +### `browser-reconnect` + +Automated: [live-update recovery](../ui/src/context/LiveUpdatesProvider.recovery.test.tsx) +covers client transport recovery with mocks. It does not prove runner restart. + +Manual: go offline during a disposable run, let the server reach a new state, +then reconnect. Confirm task/run/attention data refresh without duplicate +comments or decisions; reload and compare. A healthy websocket proves transport +only. Separately inspect the underlying execution if it is still stuck. + +## Gotchas + +- Legacy and native runtimes have different ownership and restart paths. Record + which one was exercised instead of inferring coverage from the adapter name. +- A process disappearance, elapsed timeout, or successful API retry does not + prove an external tool operation never happened. Unknown outcomes stay unknown + until corroborated; automatic replay can duplicate a side effect. +- Active-run watchdogs, task watchdogs, reviewers, and recovery owners have + different authority. No recovery card grants board permission by itself. +- Idle Agent Chat is not stranded work. An intentional operator stop must not + silently trigger recovery that fights the user's instruction. +- Source inspection and mocked component tests do not qualify real server + restart continuity. Use the appropriate runtime suite for that claim. +- See [execution semantics](../doc/execution-semantics.md) for the governing + recovery contract and [steering](./steering.md) for saved follow-ups. diff --git a/feature-map/routines.md b/feature-map/routines.md new file mode 100644 index 0000000000..c951e17091 --- /dev/null +++ b/feature-map/routines.md @@ -0,0 +1,45 @@ +# Routines, schedules, and triggers + +Operators define repeatable work, configure its inputs and triggers, run it on demand or automatically, and inspect the execution history and resulting tasks. + +Implementation: [routine list](../ui/src/pages/Routines.tsx), [routine detail](../ui/src/pages/RoutineDetail.tsx), [trigger editor](../ui/src/components/routine-triggers/TriggerWizard.tsx). + +## Sub-features + +- `definition`: save the request, agent, project, variables, and execution context. +- `triggers`: configure supported schedules/webhooks or other offered triggers. +- `run-now`: supply inputs and create an observable routine execution. +- `history`: inspect resulting tasks and past outcomes. +- `management`: organize, pause/disable, archive, and distinguish plugin-managed routines. + +## How to get to it (user POV) + +### `routine-editor` + +Open `/routines`, create one, and inspect `/routines/:routineId` and its edit sections. + +### `trigger-history` + +Use the routine’s trigger controls and History/Audit links; lists also offer Run now. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a disposable routine, deterministic test agent, and harmless target. Record schedule timezone and enabled state. + +### `routine-editor` + +Automated: [routine detail helper](../ui/src/pages/RoutineDetail.test.tsx) tests project-selector options, not the rendered editor. [Routine service](../server/src/__tests__/routines-service.test.ts) covers server contracts. Saving and running through the editor remain manual checks. + +Manual: Save an agent, request, project, and a required variable. Reload and inspect the saved definition. Run now with a distinguishable input, follow the resulting task, and verify its output and history entry. Check a missing required input. + +### `trigger-history` + +Automated: [trigger wizard](../ui/src/components/routine-triggers/TriggerWizard.test.tsx) is component coverage; [routine integration](../server/src/__tests__/routines-e2e.test.ts) is server integration rather than a provider-wide browser proof. + +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. + +## Gotchas + +- Saving a schedule does not prove the scheduler invoked it. +- Timezone, overlap/concurrency rules, and plugin ownership affect behavior. +- A routine run’s task must still respect pause, access, and budget gates. diff --git a/feature-map/runs-adapters.md b/feature-map/runs-adapters.md new file mode 100644 index 0000000000..6b1f1a4f1e --- /dev/null +++ b/feature-map/runs-adapters.md @@ -0,0 +1,44 @@ +# Runs, harnesses, and model accounts + +Operators choose an agent harness and model account, inspect execution history and transcripts, and distinguish a working configuration from a successful task result. + +Implementation: [adapter manager](../ui/src/pages/AdapterManager.tsx), [run host](../ui/src/pages/AgentDetail.tsx), [configuration](../ui/src/components/AgentConfigForm.tsx). + +## Sub-features + +- `availability`: discover installed adapters and available models/accounts. +- `validation`: test an adapter in the selected execution environment and surface authentication failures. +- `runs`: inspect run status, events, output, costs, and the source task. +- `session`: preserve or reset execution context through supported lifecycle actions. + +## How to get to it (user POV) + +### `adapter-setup` + +Open an agent’s model/adapter configuration or the instance adapter settings page when permitted. + +### `run-history` + +Open an agent run at `/agents/:agentId/runs/:runId` from the agent or task activity. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Record adapter, model, account, native/legacy runtime, and environment. Capabilities vary; one harness result is not a matrix-wide qualification. + +### `adapter-setup` + +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. + +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. + +### `run-history` + +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. + +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. + +## Gotchas + +- The run log is instance database data; it is not the opt-out first-party Telemetry system or operator-configured OpenTelemetry tracing. +- Authentication/model discovery does not establish tool, image, steering, or resumption capability parity. +- Use [recovery](./recovery.md) for interrupted runs and [execution environments](./execution-environments.md) for local/SSH/sandbox differences. diff --git a/feature-map/secrets.md b/feature-map/secrets.md new file mode 100644 index 0000000000..71dcfb7c26 --- /dev/null +++ b/feature-map/secrets.md @@ -0,0 +1,45 @@ +# Secrets, personal credentials, and proposals + +Operators manage company secret references, users supply their own credentials where required, and reviewers decide proposed secret changes without exposing secret values in ordinary UI evidence. + +Implementation: [secrets page](../ui/src/pages/Secrets.tsx), [personal secrets](../ui/src/pages/secrets/MyUserSecretsTab.tsx), [proposals](../ui/src/pages/secrets/ProposalsTab.tsx). + +## Sub-features + +- `company-secrets`: create/update secret references and control their bindings. +- `user-secrets`: define required user credentials and set a value for the current user. +- `proposals`: review proposed changes with the appropriate authority. +- `vault-import`: import eligible external-vault references through the offered flow. +- `runtime-delivery`: deliver only the secret references authorized for the run/actor. + +## How to get to it (user POV) + +### `secret-management` + +Open company Settings → Secrets and the company/personal secret views. + +### `proposal-import` + +Use the Proposals tab or Import from vault where available. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use dummy credentials in an isolated company, two user identities, and a test agent. Never print actual secret values in evidence. + +### `secret-management` + +Automated: [secrets service](../server/src/__tests__/secrets-service.test.ts) and [user ownership](../server/src/__tests__/secrets-service-user-secret-owner-scoped.test.ts) cover storage/access contracts. + +Manual: Create a dummy secret reference, bind it through a supported field, and verify its use in a harmless run without logging the value. Update it and reload. Switch users and confirm personal values remain owner-scoped and missing credentials produce an actionable state. + +### `proposal-import` + +Automated: [proposal routes](../server/src/__tests__/secret-proposals-routes.test.ts) and [vault import dialog](../ui/src/pages/secrets/ImportFromVaultDialog.test.tsx) cover route/UI layers; a real vault integration needs live validation. + +Manual: Review a dummy proposal, reject one and accept another, then inspect the resulting reference state and history. Preview a vault import, select only disposable entries, and verify imported references and denied-access errors after reload. + +## Gotchas + +- A displayed reference name is not proof that the actor can resolve its value at runtime. +- Company secrets and user-specific values have different ownership. +- Redaction needs verification in errors, activity, and run logs as well as the form. diff --git a/feature-map/skills.md b/feature-map/skills.md new file mode 100644 index 0000000000..c8565f2b2a --- /dev/null +++ b/feature-map/skills.md @@ -0,0 +1,55 @@ +# Skill discovery, authoring, and policy + +Operators discover or import skills, author and test them in Skill Studio, manage source versions, and decide which agents may use them. + +Implementation: [skill library](../ui/src/pages/CompanySkills.tsx), [studio](../ui/src/pages/SkillStudio.tsx), [sources](../ui/src/pages/SkillSources.tsx), [agent skills](../ui/src/pages/agent-skills/AgentSkillsTab.tsx). + +## Sub-features + +- `discovery`: browse installed/discover views and import a skill or source. +- `authoring`: create/edit a writable skill or fork a read-only source. +- `versions`: inspect revisions, source updates, diffs, and selected releases. +- `policy`: apply agent enablement and skill usage policy independently from installation. +- `testing`: run a bounded Studio test and inspect its result and interactions. + +## How to get to it (user POV) + +### `library-sources` + +Open `/skills`, Discover, or `/skills/sources`; project import is available through the library’s import flow. + +### `studio` + +Use New skill or `/skills/studio/:skillId`; writable copies and source-backed originals differ. + +### `agent-enablement` + +Use skill policy/agent selection in the library or an agent’s Skills tab. + +## Driving it + +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` + +Automated: [library UI](../ui/src/pages/CompanySkills.test.tsx) and [source service](../server/src/__tests__/skill-sources.test.ts) cover their respective layers. + +Manual: Install a fixture, locate it in Installed, inspect its source and files, and reload. Import a source update and compare versions before accepting it. Check a source requiring unavailable repository access and verify the failure is explicit. + +### `studio` + +Automated: [Studio](../ui/src/pages/SkillStudio.test.tsx) covers UI behavior; model-driven skill testing remains a separate manual result. + +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. + +### `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. + +Manual: Enable the skill for one test agent and leave another without access. Run a small task on each, inspect the available skill context, then change the release/policy and verify the next eligible run uses the intended version. + +## Gotchas + +- Installed does not mean enabled for every agent. +- Read-only GitHub/bundled skills may require a writable copy rather than an in-place edit. +- Studio interaction coverage is in [questions and approvals](./questions-and-approvals.md); a passing mock is not a live harness test. diff --git a/feature-map/status-cards.md b/feature-map/status-cards.md new file mode 100644 index 0000000000..ec0b2b240c --- /dev/null +++ b/feature-map/status-cards.md @@ -0,0 +1,44 @@ +# Status cards and refreshed summaries + +The status-card experiment turns a saved prompt/query into an inspectable summary of watched work, with refresh history, configuration, and archive/restore controls. + +Implementation: [status page](../ui/src/pages/StatusCards/index.tsx), [card detail](../ui/src/pages/StatusCards/StatusCardDetailDrawer.tsx). + +## Sub-features + +- `authoring`: create a card and configure its prompt, refresh behavior, and summarizer. +- `generation`: observe compilation/refresh tasks and their successful or failed output. +- `inspection`: read the summary, watched work, history, and available query debugging. +- `archive`: archive and restore without confusing a stale summary with a current result. + +## How to get to it (user POV) + +### `status-board` + +Open `/status`, choose New card, and follow a card at `/status/:cardId`. + +### `card-settings` + +Open the card detail’s settings/query-debug controls and archive/restore actions. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enable status cards, use a configured summarizer and disposable tasks, and record whether summary generation is simulated or live. + +### `status-board` + +Automated: [status-card service/routes](../server/src/__tests__/status-cards.test.ts) covers gated lifecycle and generation contracts; [tile UI](../ui/src/pages/StatusCards/StatusCardTile.test.tsx) covers rendering. + +Manual: Create a bounded card, inspect its generation task, and wait for a saved summary. Change a watched task, refresh, and verify both the summary and update history reflect the source change. Exercise a failed generation and confirm it is not presented as fresh. + +### `card-settings` + +Automated: [settings form](../ui/src/pages/StatusCards/StatusCardSettingsForm.test.tsx) and [update engine](../server/src/__tests__/status-card-update-engine.test.ts) cover separate UI/engine layers. + +Manual: Change a disposable card’s prompt or summarizer, run the offered rebuild/refresh, and inspect the resulting query and summary. Archive and restore it, reload its direct link, and check the actual new generation outcome. + +## Gotchas + +- Summary quality needs comparison against source work, not just a successful task status. +- A saved old summary must not be counted as a successful new refresh. +- Experimental visibility, author permissions, and agent ownership constrain mutation. diff --git a/feature-map/steering.md b/feature-map/steering.md new file mode 100644 index 0000000000..02d1cfa91b --- /dev/null +++ b/feature-map/steering.md @@ -0,0 +1,135 @@ +# Steering and queued messages + +People can send follow-ups while an agent works, manage saved messages that have +not been consumed, and choose when to steer or interrupt. Stopping a run and +pausing a task are separate controls. The UI must preserve the message, explain +why it is waiting, and only claim delivery after an authoritative acknowledgement. + +## Sub-features + +- `queue`: a busy task saves follow-ups and shows their order and wait reason. +- `edit-order-discard`: edit full Markdown, reorder, and discard eligible saved + messages; ownership, revision conflicts, and already-dispatched states matter. +- `steer`: explicit user action sends a queued message into a compatible active + run; unavailable capabilities and provider rejection remain visible. +- `interrupt`: stop the current execution and carry accepted follow-ups into + the eligible continuation without delivering them twice. +- `stop-and-pause`: distinguish stop-in-flight, confirmed stop, task/ancestor + pause, agent pause, and budget hold. Resume must respect the actual gate. +- `drafts`: switching tasks, reloading, and uncertain submission retain the + correct task's draft and attachment receipts. +- `approval-queue`: answered questions and accepted approvals have durable + delivery distinct from editable ordinary comments. + +## How to get to it (user POV) + +### `task-composer` + +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. Use the composer stop/pause control separately. +Both task presentations need attention when changing their shared behavior. + +### `agent-chat` + +Enable Agent Chat and open an agent conversation. Send another message during +a reply and inspect the shared queue. `/new` starts fresh provider context in +the same conversation; it is an ordered boundary, not a normal model prompt. + +### `request-response` + +Answer an earlier question or accept a confirmation while successor work is +active on the task. Inspect the resulting queued response and its available +steer/interrupt control instead of assuming acceptance interrupted execution. + +### `external-channel` + +Send a follow-up from a linked external chat conversation while its task is +running. Use that provider's supported stop/control affordance where available; +inspect the resulting task and run in Paperclip. + +## Driving it + +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 +unsupported steering without treating an absent capability as a product failure. + +### `task-composer` + +Automated: [queued-message UI](../ui/src/components/task-chat/TaskChatQueuedMessages.test.tsx) +covers order, failure restoration, unavailable steering, stale revisions, and +discard acknowledgements. [Queue routes](../server/src/__tests__/issue-queued-comments-routes.test.ts) +cover durable ordering, authorization, steering acknowledgements, interrupt +recovery, and concurrent dispatch. [Composer](../ui/src/components/task-chat/TaskChatComposer.test.tsx) +covers drafts and uncertain saves. + +```sh +pnpm exec vitest run ui/src/components/task-chat/TaskChatQueuedMessages.test.tsx server/src/__tests__/issue-queued-comments-routes.test.ts +``` + +Automated stop coverage is separate: +[composer stop](../tests/e2e/composer-stop.spec.ts) with +[its configuration](../tests/e2e/playwright-composer-stop.config.ts) and +[ACP stop/continuation](../tests/e2e/acp-stop-continuation.spec.ts). Inspect their +fixture and opt-in prerequisites; skipped native cases are not native proof. + +Manual: queue three distinguishable messages. Edit one, reorder them, reload, +and confirm the saved order. Discard one and confirm it never reaches execution. +Steer one while busy and verify the agent receives that exact message once. +Repeat with a rejected steer and a stale second-tab edit; the UI must preserve +retryable content and explain the conflict. On a fresh run, interrupt with a +queued follow-up and verify confirmed stop followed by one continuation. Pause +the task (and separately its ancestor), preserve a draft, then resume the actual +hold; no hidden send should occur while paused. Check both task presentations +when available; the named component tests do not prove every host integration. + +### `agent-chat` + +Automated: [agent chat sessions](../tests/e2e/agent-chat-sessions.spec.ts) covers +persistent conversation/session behavior with deterministic harness fixtures; +shared composer tests cover the controls. These do not qualify live steering +for every harness. + +Manual: queue two follow-ups while the conversation replies. Reload, edit or +discard one, then let the other run. Verify one reply and unchanged conversation +identity. Send `/new`, then a new prompt; old history remains visible, and the +new turn uses fresh provider context. Verify a useful answer rather than only +the session-divider UI. Repeat the queue operations with a live capable harness +when the change touches delivery. + +### `request-response` + +Automated: [response delivery](../server/src/__tests__/question-response-delivery.test.ts) +proves queueing/coalescing and retry-safe receipts. The queue-route suite tests +separate comment and approval queues, explicit steering, and fresh-session +restrictions on plan approvals. + +Manual: answer an old question during a new run, confirm that it is saved and +queued, and let the active run end. Verify exactly one continuation with the +answer. Repeat an eligible approval with explicit steer; another approval that +requires a fresh session must not offer same-turn delivery. Do not edit an +approval outcome through an ordinary queued-message editor. + +### `external-channel` + +Automated: [chat interaction arbitration](../server/src/services/chat-interaction-arbitration.test.ts) +covers backend arbitration with simulated requests. It is not a provider UI test. + +Manual: send two distinguishable messages through one disposable linked +conversation while busy. Inspect their saved task order, run delivery, and +external reply. Check a duplicate provider event and unauthorized sender. +Provider-specific control semantics and real transport timing remain a manual +gap; do not assume browser queue controls are available in every channel. + +## Gotchas + +- Paperclip's queue is server-owned once saved; it is not Omnigent's unsent + browser draft buffer. A stale edit must not overwrite a consumed message. +- Steer availability depends on the active runtime's capability, not its brand + name. A UI row disappearing optimistically does not prove provider receipt. +- Interrupt, stop, task pause, agent pause, and budget pause have different + effects. A running indicator disappearing does not prove remote work stopped. +- An interrupted run may need verified cleanup before a saved follow-up can + start. Preserve and inspect the wait reason; see [recovery](./recovery.md). +- A healthy idle Agent Chat is waiting for input, not stranded unfinished work. diff --git a/feature-map/task-coordination.md b/feature-map/task-coordination.md new file mode 100644 index 0000000000..9549f7606d --- /dev/null +++ b/feature-map/task-coordination.md @@ -0,0 +1,44 @@ +# Delegation, dependencies, and signoff + +A larger task can coordinate child work, dependencies, reviewers, and execution controls while preserving a clear owner and a traceable completion decision. + +Implementation: [task thread](../ui/src/pages/IssueDetail.tsx), [execution policy](../server/src/services/issues.ts). + +## Sub-features + +- `delegation`: inspect parent/child tasks and the original request behind delegated work. +- `dependencies`: show blocking tasks and wake eligible work when prerequisites resolve. +- `signoff`: apply the configured implementation/review completion policy. +- `tree-control`: pause or resume a task tree without bypassing its gates. + +## How to get to it (user POV) + +### `task-relationships` + +Open the task’s parent/child and dependency links in task detail. + +### `review-and-controls` + +Inspect the task’s execution policy and available review, pause, resume, or stop controls. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Prepare a parent, child, and dependent task plus implementer/reviewer agents. Record execution policy and use a disposable tree. + +### `task-relationships` + +Automated: [dependency wakeups](../server/src/__tests__/issue-dependency-wakeups-routes.test.ts) checks server behavior; visual relationship navigation remains a manual check. + +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` + +Automated: [execution policy](../server/src/__tests__/issue-execution-policy.test.ts), [tree control](../server/src/__tests__/issue-tree-control-service.test.ts), and [signoff browser suite](../tests/e2e/signoff-policy.spec.ts) target these layers. A linked suite is not a claim that its current run is green. + +Manual: Complete implementation under a review-required policy and confirm it waits for the required review outcome. Exercise rejection and later approval. Pause the parent while child work is pending, then verify resumption respects budget and ownership gates. + +## Gotchas + +- Review completion and task completion are different events under some policies. +- Pausing a tree must not be “tested” by changing statuses until the screen looks quiet. +- Use [questions and approvals](./questions-and-approvals.md) for decision forms and [recovery](./recovery.md) for interrupted work. diff --git a/feature-map/tasks.md b/feature-map/tasks.md new file mode 100644 index 0000000000..a2a7e42bc3 --- /dev/null +++ b/feature-map/tasks.md @@ -0,0 +1,55 @@ +# Task creation and lifecycle + +People create, assign, organize, discuss, and finish tasks. A task retains its owner, project, priority, history, and outputs as it moves through the work lifecycle. + +Implementation: [new task](../ui/src/components/NewIssueDialog.tsx), [task list](../ui/src/pages/Issues.tsx), [task detail](../ui/src/pages/IssueDetail.tsx). + +## Sub-features + +- `create`: capture a title/request with the intended agent, project, and attachments. +- `organize`: filter, sort, group, and navigate tasks without losing the selected context. +- `properties`: change status, priority, assignee, project, and relationships where authorized. +- `discussion`: persist comments, references, and files on the task. +- `completion`: distinguish backlog, active work, review, blocked, done, and cancelled outcomes. + +## How to get to it (user POV) + +### `new-task` + +Use New task from the global launcher, task list, or project task view. + +### `task-list` + +Open `/issues` or a project’s Issues view; legacy `/tasks` links redirect. + +### `task-detail` + +Open `/issues/:issueId` from a row, mention, or direct link. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use an invokable test agent and a project; record whether a real or simulated harness handles the request. + +### `new-task` + +Automated: [creation dialog](../ui/src/components/NewIssueDialog.test.tsx) is component coverage with mocked requests. + +Manual: Create a uniquely named task with an agent and project. Open its resulting link and reload. Confirm text, attachment, assignment, and project persisted, and verify execution started only when the task and agent are eligible. + +### `task-list` + +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. + +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. + +### `task-detail` + +Automated: [task detail](../ui/src/pages/IssueDetail.test.tsx) covers component behavior, while [issue service](../server/src/__tests__/issues-service.test.ts) covers server contracts. + +Manual: Add a comment and edit authorized properties. Reload and verify history, actor, and values. Complete a disposable task and inspect its deliverable; reopen through an available action and confirm the next execution follows current policy. + +## Gotchas + +- A status label alone does not prove that the requested work exists. +- Single-assignee and atomic checkout rules still apply when tasks are created from different hosts. +- Use [coordination](./task-coordination.md), [steering](./steering.md), and [documents](./documents-artifacts.md) for their distinct workflows. diff --git a/feature-map/teams.md b/feature-map/teams.md new file mode 100644 index 0000000000..a1370c75eb --- /dev/null +++ b/feature-map/teams.md @@ -0,0 +1,44 @@ +# Team packages and catalog installation + +Operators can preview and install a team package with its agents and related resources. Catalog/package installation is available through the CLI/API; the repository also contains catalog UI components that are not a current top-level route. + +Implementation: [CLI teams](../cli/src/commands/client/teams.ts), [catalog components](../ui/src/pages/TeamCatalog.tsx). + +## Sub-features + +- `discovery`: list available team catalog entries and inspect package contents. +- `preview`: inspect proposed resources and installation options before mutation. +- `install`: install into the intended company and inspect resulting agents and resources. +- `configuration`: supply required adapters/accounts and verify installed agents can work. + +## How to get to it (user POV) + +### `catalog-cli` + +Use the CLI teams catalog/preview/install operations in the selected context. + +### `catalog-components` + +The catalog components and install wizard are available in developer tests/design surfaces. No top-level `/teams` route is registered; use the CLI/API for the current installation workflow. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a disposable company, a small catalog entry, and explicit company context. Check `paperclipai teams --help` for current subcommands. + +### `catalog-cli` + +Automated: [team commands](../cli/src/__tests__/teams.test.ts) and [catalog service](../server/src/__tests__/teams-catalog-service.test.ts) cover command and service contracts. + +Manual: List an entry, preview its proposed agents and resources, install it into the disposable company, and inspect each created resource. Run a small task after configuring accounts. Retry preview/install as supported and inspect duplicate/conflict behavior. + +### `catalog-components` + +Automated: [catalog component](../ui/src/pages/TeamCatalog.test.tsx) and [install hook](../ui/src/pages/useInstallTeamCatalogEntry.test.tsx) cover preview and install UI logic with mocks. + +Manual: When changing or mounting these components, exercise preview, manager/source options, cancellation, failed install, and success. Follow created agents in the actual company. Record whether this was a component harness or a real product entry point. + +## Gotchas + +- Source files do not prove that a screen is reachable in the current app. +- Installed team configuration may still need credentials or environment setup. +- Company package import is a separate [portability](./companies.md) workflow. diff --git a/feature-map/workspaces.md b/feature-map/workspaces.md new file mode 100644 index 0000000000..d7b24fca7c --- /dev/null +++ b/feature-map/workspaces.md @@ -0,0 +1,45 @@ +# Execution workspaces, services, and files + +A project or task can use a managed workspace with inspectable files, Git state, services, and runtime controls. Operators can follow its lifecycle through provisioning, use, and closure. + +Implementation: [workspace list](../ui/src/pages/Workspaces.tsx), [execution workspace](../ui/src/pages/ExecutionWorkspaceDetail.tsx), [project workspace](../ui/src/pages/ProjectWorkspaceDetail.tsx). + +## Sub-features + +- `binding`: identify the workspace actually bound to a task/run. +- `provisioning`: observe readiness and failures instead of inferring readiness from a created record. +- `services`: start/stop supported services and inspect logs and exposed endpoints. +- `files-git`: inspect workspace files and repository state used for the deliverable. +- `closure`: close/reopen or reconcile through permitted controls without losing work. + +## How to get to it (user POV) + +### `task-workspace` + +Use the task’s workspace card or Files panel and follow its workspace link. + +### `workspace-management` + +Open `/workspaces`, a project workspace, or `/execution-workspaces/:workspaceId` and its Services/Configuration/Runtime logs views. + +## Driving it + +Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Enable isolated-workspace UI where needed. Use an owned disposable repository and environment; record workspace ID and branch. + +### `task-workspace` + +Automated: [workspace card](../ui/src/components/IssueWorkspaceCard.test.tsx) and [task binding](../server/src/__tests__/issue-runtime-workspace-binding.test.ts) cover host/binding contracts. + +Manual: Run a task that writes a small file, follow the bound workspace, and inspect the file and revision. Reload and verify links still refer to the same workspace, not another checkout or a stale run. + +### `workspace-management` + +Automated: [workspace detail](../ui/src/pages/ExecutionWorkspaceDetail.test.tsx) and [runtime service](../server/src/__tests__/workspace-runtime.test.ts) cover UI and runtime contracts separately. + +Manual: Provision a disposable workspace, wait for readiness, start an available service, open its endpoint, and inspect a real response and logs. Stop it and verify it actually stops. Exercise close/reopen only after inspecting pending changes and active runs. + +## Gotchas + +- A link or running badge does not prove the service is reachable from the user’s browser. +- Workspace IDs, runtime leases, and repository paths are not interchangeable. +- Use [recovery](./recovery.md) for divergence/export repair and [CLI operations](./cli-operations.md) for local worktree tooling.