Add deployment guidelines, assets/attachments spec, and humans-and-permissions plan

Document local-trusted vs cloud-hosted deployment scenarios in
PRODUCT.md. Spec out assets and issue_attachments tables with storage
provider abstraction and attachment API endpoints. Draft comprehensive
plan for human users, memberships, invites, permissions, and
agent-to-human task delegation across both deployment modes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-20 11:28:58 -06:00
parent fe1ede32b6
commit ad748349cb
3 changed files with 273 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ Paperclip is the control plane for autonomous AI companies. One instance of Pape
### Company
A company has:
- A **goal** — the reason it exists ("Create the #1 AI note-taking app that does $1M MRR within 3 months")
- **Employees** — every employee is an AI agent
- **Org structure** — who reports to whom
@@ -20,6 +21,7 @@ A company has:
Every employee is an agent. When you create a company, you start by defining the CEO, then build out from there.
Each employee has:
- **Adapter type + config** — how this agent runs and what defines its identity/behavior. This is adapter-specific (e.g., an OpenClaw agent might use SOUL.md and HEARTBEAT.md files; a Claude Code agent might use CLAUDE.md; a bare script might use CLI args). Paperclip doesn't prescribe the format — the adapter does.
- **Role & reporting** — their title, who they report to, who reports to them
- **Capabilities description** — a short paragraph on what this agent does and when they're relevant (helps other agents discover who can help with what)
@@ -80,6 +82,13 @@ More detailed task structure TBD.
6. Set budgets, define initial strategic tasks
7. Hit go — agents start their heartbeats and the company runs
## Guidelines
There are two deployment scenarios that need to be maintained:
- a single user, local trusted deployment - this should be easy to install with a single `npx paperclip run` command and the environment is trusted and self-contained on a local machine (e.g. local files, agents, embedded db, easy to use)
- multi-user cloud deployment - allows for a hosted deploy (remote deployment, user logins, hosted db, scalable)
## Further Detail
See [SPEC.md](./SPEC.md) for the full technical specification and [TASKS.md](./TASKS.md) for the task management data model.

View File

@@ -95,6 +95,9 @@ V1 implementation extends this baseline into a company-centric, governance-aware
- Local default: embedded PostgreSQL at `~/.paperclip/instances/default/db`
- Optional local prod-like: Docker Postgres
- Optional hosted: Supabase/Postgres-compatible
- File/object storage:
- local default: `~/.paperclip/instances/default/data/storage` (`local_disk`)
- cloud: S3-compatible object storage (`s3`)
## 6.3 Background Processing
@@ -302,9 +305,32 @@ Operational policy:
- `heartbeat_runs(company_id, agent_id, started_at desc)`
- `approvals(company_id, status, type)`
- `activity_log(company_id, created_at desc)`
- `assets(company_id, created_at desc)`
- `assets(company_id, object_key)` unique
- `issue_attachments(company_id, issue_id)`
- `company_secrets(company_id, name)` unique
- `company_secret_versions(secret_id, version)` unique
## 7.14 `assets` + `issue_attachments`
- `assets` stores provider-backed object metadata (not inline bytes):
- `id` uuid pk
- `company_id` uuid fk not null
- `provider` enum/text (`local_disk | s3`)
- `object_key` text not null
- `content_type` text not null
- `byte_size` int not null
- `sha256` text not null
- `original_filename` text null
- `created_by_agent_id` uuid fk null
- `created_by_user_id` uuid/text fk null
- `issue_attachments` links assets to issues/comments:
- `id` uuid pk
- `company_id` uuid fk not null
- `issue_id` uuid fk not null
- `asset_id` uuid fk not null
- `issue_comment_id` uuid fk null
## 8. State Machines
## 8.1 Agent Status
@@ -420,6 +446,10 @@ All endpoints are under `/api` and return JSON.
- `POST /issues/:issueId/release`
- `POST /issues/:issueId/comments`
- `GET /issues/:issueId/comments`
- `POST /companies/:companyId/issues/:issueId/attachments` (multipart upload)
- `GET /issues/:issueId/attachments`
- `GET /attachments/:attachmentId/content`
- `DELETE /attachments/:attachmentId`
### 10.4.1 Atomic Checkout Contract

View File

@@ -0,0 +1,234 @@
# Humans and Permissions Plan
Status: Draft
Date: 2026-02-20
Owner: Server + UI + Shared + DB
## Goal
Add first-class human users and permissions while preserving two deployment modes:
- local trusted single-user mode with no login friction
- cloud-hosted multi-user mode with mandatory authentication and authorization
## Why this plan
Current V1 assumptions are centered on one board operator. We now need:
- multi-human collaboration with per-user permissions
- safe cloud deployment defaults (no accidental loginless production)
- local mode that still feels instant (`npx paperclip run` and go)
- agent-to-human task delegation, including a human inbox
## Product constraints
1. Keep company scoping strict for every new table, endpoint, and permission check.
2. Preserve existing control-plane invariants:
- single-assignee task model
- approval gates
- budget hard-stop behavior
- mutation activity logging
3. Keep local mode easy and trusted, but prevent unsafe cloud posture.
## Deployment modes
## Mode A: `local_trusted`
Behavior:
- no login UI
- browser opens directly into board context
- embedded DB and local storage defaults remain
- a local implicit human actor exists for attribution
Guardrails:
- server binds to loopback by default
- refuse startup if mode is `local_trusted` with non-loopback bind, unless explicit `--allow-unsafe-local-network`
- UI shows a persistent "Local trusted mode" badge
## Mode B: `cloud_hosted`
Behavior:
- login required for all human endpoints
- hosted DB and remote deployment supported
- multi-user sessions and role/permission enforcement
Guardrails:
- fail startup if auth provider/session config is missing
- fail startup if insecure auth bypass flag is set
- health payload includes mode and auth readiness
## Auth and actor model
Unify request actors into a single model:
- `user` (authenticated human)
- `agent` (API key)
- `local_board_implicit` (local trusted mode only)
Rules:
- in `cloud_hosted`, only `user` and `agent` are valid actors
- in `local_trusted`, unauthenticated browser/API requests resolve to `local_board_implicit`
- all mutating actions continue writing `activity_log` with actor type/id
## Data model additions
## New tables
1. `users`
- identity record for human users (email-based)
2. `company_memberships`
- `company_id`, `user_id`, status, role metadata
- stores effective permissions and optional org scope constraints
3. `invites`
- `company_id`, invite email, token hash, expires_at, invited_by, revoked_at, accepted_at
- optional default permissions payload at invite time
4. `user_permission_grants` (or JSON grant blob in membership)
- explicit grants such as `agents:create`
- includes scope payload for chain-of-command limits
5. `issues` extension
- add `assignee_user_id` nullable
- preserve single-assignee invariant with XOR check:
- exactly zero or one of `assignee_agent_id` / `assignee_user_id`
## Compatibility
- existing `created_by_user_id` / `author_user_id` fields remain and become fully active
- agent API key model remains unchanged, still company-scoped
## Permission model (initial set)
Core grants:
1. `agents:create`
2. `users:invite`
3. `users:manage_permissions`
4. `tasks:assign`
5. `tasks:assign_scope` (org-constrained delegation)
Additional behavioral rules:
- board-level users can manage all grants
- non-board users can only act within explicit grants
- assignment checks apply to both agent and human assignees
## Chain-of-command scope design
Initial approach:
- represent assignment scope as an allow rule over org hierarchy
- examples:
- `subtree:<agentId>` (can assign into that manager subtree)
- `exclude:<agentId>` (cannot assign to protected roles, e.g., CEO)
Enforcement:
- resolve target assignee org position
- evaluate allow/deny scope rules before assignment mutation
- return `403` for out-of-scope assignments
## Invite and signup flow
1. Authorized user creates invite with email + grants + optional expiry.
2. System sends invite URL containing one-time token.
3. Invitee signs up/logs in.
4. Email on authenticated account must match invite email.
5. Accepting invite creates active `company_membership` and permission grants.
6. Inviter/admin can revoke invite before acceptance.
Security rules:
- store invite token hashed at rest
- one-time use token with short expiry
- all invite lifecycle events logged in `activity_log`
## Human inbox and agent-to-human delegation
Behavior:
- agents can assign tasks to humans when policy permits
- humans see assigned tasks in inbox view (including in local trusted mode)
- comment and status transitions follow same issue lifecycle guards
API additions (proposed):
- `GET /companies/:companyId/inbox` (human actor scoped to self)
- `POST /companies/:companyId/issues/:issueId/assign-user`
- `POST /companies/:companyId/invites`
- `POST /invites/:token/accept`
- `POST /invites/:inviteId/revoke`
- `GET /companies/:companyId/members`
- `PATCH /companies/:companyId/members/:userId/permissions`
## Local mode UX policy
- no login prompt or account setup required
- local implicit board user is auto-provisioned for audit attribution
- invite/multi-user screens can be hidden or marked unavailable in local mode
- if operator wants collaboration, they must switch to `cloud_hosted`
## Cloud agents in this model
- cloud agents continue authenticating through `agent_api_keys`
- same-company boundary checks remain mandatory
- agent ability to assign human tasks is permission-gated, not implicit
## Implementation phases
## Phase 1: Mode and guardrails
- add explicit deployment mode config (`local_trusted | cloud_hosted`)
- enforce startup safety checks and health visibility
- implement actor resolution for local implicit board
## Phase 2: Human identity and memberships
- add schema + migrations for users/memberships/invites
- wire auth middleware for cloud mode
- add membership lookup and company access checks
## Phase 3: Permissions and assignment scope
- add grant model and enforcement helpers
- add chain-of-command scope checks for assignment APIs
- add tests for forbidden assignment (for example, cannot assign to CEO)
## Phase 4: Invite workflow
- invite create/send/accept/revoke endpoints
- email-match enforcement and token security
- UI for invite management and membership permissions
## Phase 5: Human inbox + task assignment updates
- extend issue assignee model for human users
- inbox API and UI
- agent-to-human assignment flow with policy checks
## Acceptance criteria
1. `local_trusted` starts with no login and shows board UI immediately.
2. `cloud_hosted` cannot start without auth configured.
3. No request in `cloud_hosted` can mutate data without authenticated actor.
4. Humans can be invited by email, accepted with matching email, and revoked.
5. Permissions can be granted/revoked per company member.
6. Assignment scope prevents out-of-hierarchy or protected-role assignments.
7. Agents can assign tasks to humans only when allowed.
8. Humans can view assigned tasks in inbox and act on them per permissions.
9. All new mutations are company-scoped and logged in `activity_log`.
## Open decisions
1. Auth provider choice for cloud mode (Auth.js vs hosted provider).
2. Whether local mode supports optional login in addition to implicit board.
3. Exact representation of permission grants (normalized table vs JSON schema).
4. Whether a user can belong to multiple companies in initial release.
5. Whether invite email delivery is built-in or webhook/provider integration only.