mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-09 07:10:34 +01:00
## Thinking Path > - Paperclip coordinates agents that make and verify repository changes. > - Local verification currently defaults to the complete Vitest suite. > - Contributor instructions also require broad local checks at each PR handoff. > - CI already owns conservative affected-test selection and broad final-revision checks. > - This pull request adds local selection and pass reuse from those existing contracts. > - Agents can get focused feedback and use CI to close the remaining coverage gaps. ## Linked Issues or Issue Description **Subsystem affected** Developer verification scripts and contributor guidance. Related selection work: #18398 and #18464. **Problem or motivation** An agent that repeats an unchanged local verification step starts the complete suite again. The handoff guidance also duplicates broad CI coverage locally. **Proposed solution** Add `pnpm verify` for the actual working tree. Select affected Vitest specifications with the CI task policy and dependency graph. Reuse successful checks whose inputs are modeled. Run opaque checks fresh. Report exit 2 when broader verification is required. Update the contributor contract to accept applicable final-revision CI coverage. **Alternatives considered** Plain `vitest related` omits filesystem and opaque dependencies. Commit-only cache keys miss dirty files. Running full local suites at every handoff repeats CI work. **Roadmap alignment** This is repository development tooling. It does not change the product roadmap. ## What Changed - Add `pnpm verify`, `--explain`, `--base`, `--full`, and `--no-cache`. - Reuse CI selection and exact runner ownership for dirty, staged, committed, deleted, renamed, and untracked inputs. - Keep native server suites and serialized suites in their local owners. Keep six sequential chat shards. - Cache selected passes within one worktree. Hash source, fixtures, installed package contents, dependency bindings and installation metadata, dotenv files, child environment, toolchains, platform, and selection. - Run opaque consumers fresh. Preserve failed, interrupted, mutated-input, and partial-coverage outcomes. - Update AGENTS.md, CONTRIBUTING.md, and DEVELOPING.md guidance. Record the shared `verify` command as the sole exception to the package-script rule. Register the new tests in the existing CI contract-test command. - Add optional root/environment inputs to shared graph helpers. Existing CI defaults stay the same. ## Verification - Fourteen new integration tests pass locally across focused runs with real Vitest selection and execution; CI colors are covered. - 51 existing targeted selector/input, project-isolation, and stable-runner checks passed. Four relevant runner contracts also pass after the workspace change. - Repeated unchanged execution skips reusable tests. Source, environment, installed code, dependency bindings, and new untracked tests invalidate results. - Installed-code mutation with a restored modification time still invalidates a cached pass. Internal skill-directory links preserve reuse. - Workspace B/C tests prove discovery, reusable/fresh partition execution, pass reuse, and external-input failure. Chat selection produces exactly six single-worker partitions. - A deliberate unrelated failing test is omitted by narrow selection and caught by `--full`. - Red/green regressions prove fingerprints preserve file boundaries and reject edits made between diff discovery and snapshotting. - Opaque external-file changes still fail on a subsequent run. Source mutation and process interruption cannot publish reusable passes. - `pnpm verify --explain` works in the checkout and requests broad CI coverage for this tooling change. No duplicate full local suite was started. - [Final-revision CI](https://github.com/paperclipai/paperclip/actions/runs/42117291789) passed on `ed85d96ddff82c05c325948680b593b0f48c473d` (attempt 2). The scoped Canary retry preserved all passing test/build results. - [Greptile review](https://github.com/paperclipai/paperclip/pull/19345#issuecomment-6670050175) is 5/5; all four review threads are resolved. - The additional Paperclip review concluded neutral because its execution stopped; it produced no assessment. ## Risks - Pass reuse depends on conservative dependency classification. Opaque consumers, external database/live settings, and non-isolated projects retain fresh or broad coverage. - Local passes cover selected Vitest checks. Required CI, build/typecheck, release, browser, and platform acceptance remain separate obligations. - Cross-worktree caching and cross-agent scheduling are outside this change. - The initial installation scan reads dependency contents; stat-validated, worktree-local digest memoization avoids rereading unchanged contents. Subsequent scans still inspect file identity and nanosecond change/modification times. - No dependency lockfile or workflow changes. ## Model Used OpenAI Codex, `gpt-6.1-sol`, max reasoning, with local shell and file tools. Context window size is not exposed by this host. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
299 lines
15 KiB
Markdown
299 lines
15 KiB
Markdown
# AGENTS.md
|
|
|
|
Guidance for human and AI contributors working in this repository.
|
|
|
|
## 1. Purpose
|
|
|
|
Paperclip is a control plane for AI-agent companies.
|
|
The current implementation target is V1 and is defined in `doc/SPEC-implementation.md`.
|
|
|
|
## 2. Read This First
|
|
|
|
Before making changes, read in this order:
|
|
|
|
1. `doc/GOAL.md`
|
|
2. `doc/PRODUCT.md`
|
|
3. `doc/SPEC-implementation.md`
|
|
4. `doc/DEVELOPING.md`
|
|
5. `doc/DATABASE.md`
|
|
|
|
`doc/SPEC.md` is long-horizon product context.
|
|
`doc/SPEC-implementation.md` is the concrete V1 build contract.
|
|
|
|
When adding or changing an Apps catalog connection, also follow
|
|
`doc/connections/CONNECTOR-PLAYBOOK.md`. It is the canonical connection
|
|
authoring runbook for provider research, supported transport/auth patterns,
|
|
credential handling, branding, implementation, testing, live proof, and PR
|
|
submission.
|
|
|
|
### Scoped repository rules
|
|
|
|
Before editing or reviewing files, read the matching rules in `rules/*.mdc`.
|
|
Each rule has Markdown content and YAML frontmatter: `globs` contains
|
|
comma-separated, repository-relative file patterns, and `alwaysApply: true`
|
|
means the rule applies throughout the repository. Read all rules whose scope
|
|
matches the affected files. These rules supplement this file and any applicable
|
|
nested `AGENTS.md` instructions.
|
|
|
|
For `server/src/services/chat-channels.ts` and everything under
|
|
`server/src/services/chat-channels/`, read
|
|
[`rules/chat-channel-platform-boundaries.mdc`](rules/chat-channel-platform-boundaries.mdc).
|
|
For `server/src/services/heartbeat.ts`, `server/src/services/heartbeat/`,
|
|
heartbeat-prefixed sibling services, and heartbeat regression tests, read
|
|
[`rules/heartbeat-execution-boundaries.mdc`](rules/heartbeat-execution-boundaries.mdc).
|
|
For ACPX provider profiles, their release attestations and pins, the provider-pack
|
|
contract registry, and ACPX driver and provider code under
|
|
`packages/paperclip-runner/`, read
|
|
[`rules/acpx-profile-identity.mdc`](rules/acpx-profile-identity.mdc).
|
|
See [`rules/README.md`](rules/README.md) for rule authoring and Greptile setup.
|
|
|
|
## 3. Repo Map
|
|
|
|
- `server/`: Express REST API and orchestration services
|
|
- `ui/`: React + Vite board UI
|
|
- `packages/db/`: Drizzle schema, migrations, DB clients
|
|
- `packages/shared/`: shared types, constants, validators, API path constants
|
|
- `packages/adapters/`: agent adapter implementations (Claude, Codex, Cursor, etc.)
|
|
- `packages/adapter-utils/`: shared adapter utilities
|
|
- `packages/plugins/`: plugin system packages
|
|
- `packages/skills-catalog/`: app-shipped skills catalog (`@paperclipai/skills-catalog`)
|
|
- `packages/teams-catalog/`: app-shipped teams catalog (`@paperclipai/teams-catalog`)
|
|
- `cli/`: `paperclipai` CLI package (published bin, agent-facing commands)
|
|
- `skills/`: Paperclip runtime/operational skills (not part of the app catalog)
|
|
- `doc/`: operational and product docs
|
|
|
|
## 4. Dev Setup (Auto DB)
|
|
|
|
Use embedded PGlite in dev by leaving `DATABASE_URL` unset.
|
|
|
|
```sh
|
|
pnpm install
|
|
pnpm dev
|
|
```
|
|
|
|
This starts:
|
|
|
|
- API: `http://localhost:3100`
|
|
- UI: `http://localhost:3100` (served by API server in dev middleware mode)
|
|
|
|
Quick checks:
|
|
|
|
```sh
|
|
curl http://localhost:3100/api/health
|
|
curl http://localhost:3100/api/companies
|
|
```
|
|
|
|
Reset local dev DB:
|
|
|
|
```sh
|
|
rm -rf data/pglite
|
|
pnpm dev
|
|
```
|
|
|
|
## 5. Core Engineering Rules
|
|
|
|
1. Keep changes company-scoped.
|
|
Every domain entity should be scoped to a company and company boundaries must be enforced in routes/services.
|
|
|
|
Explicit exception: announcement dismissals are instance-wide user preferences,
|
|
keyed by user and announcement so they persist across companies. Their audit
|
|
context must still validate company membership. The announcement publication-ID
|
|
registry is instance-level feed metadata; it contains no company or user data.
|
|
Personal workspace presentation preferences are also instance-wide by user, with
|
|
validated company membership supplying audit context. They never grant execution
|
|
authority, change company capabilities or agent configuration, or rewrite canonical
|
|
work records. Optional conversation guidance must retain the same action permissions.
|
|
|
|
2. Keep contracts synchronized.
|
|
If you change schema/API behavior, update all impacted layers:
|
|
- `packages/db` schema and exports
|
|
- `packages/shared` types/constants/validators
|
|
- `server` routes/services
|
|
- `ui` API clients and pages
|
|
|
|
3. Preserve control-plane invariants.
|
|
- Single-assignee task model
|
|
- Atomic issue checkout semantics
|
|
- Approval gates for governed actions
|
|
- Budget hard-stop auto-pause behavior
|
|
- Activity logging for mutating actions
|
|
|
|
4. Do not replace strategic docs wholesale unless asked.
|
|
Prefer additive updates. Keep `doc/SPEC.md` and `doc/SPEC-implementation.md` aligned.
|
|
|
|
5. Keep repo plan docs dated and centralized.
|
|
When you are creating a plan file in the repository itself, new plan documents belong in `doc/plans/` and should use `YYYY-MM-DD-slug.md` filenames. This does not replace Paperclip issue planning: if a Paperclip issue asks for a plan, update the issue `plan` document per the `paperclip` skill instead of creating a repo markdown file.
|
|
|
|
6. Attach inspectable generated artifacts.
|
|
When your task produces a user-inspectable deliverable file, follow the Paperclip skill's "Generated Artifacts and Work Products" workflow before final disposition. In this repo, prefer the self-contained skill helper at `skills/paperclip/scripts/paperclip-upload-artifact.sh` so the file is available through the Paperclip API, create/update an artifact work product when the file is the deliverable, link the uploaded artifact in the final issue comment, and then set status. Do not rely on local filesystem paths as the only access path. If an important file intentionally remains workspace-only, create/update a work product with `metadata.resourceRef.kind: "workspace_file"` and a workspace-relative path, then name that work product and path in the final comment. Treat browse/search as a fallback for recovering workspace files, not the preferred deliverable path. See `doc/AGENT-ARTIFACTS.md` for details and `.mp4`/`.webm` examples.
|
|
|
|
7. Name the three data paths correctly.
|
|
This repo has three separate data paths. Do not confuse them. Match a change to a path by its file path, not by the word "observability" or "telemetry" alone.
|
|
|
|
- **Telemetry** is the Paperclip first-party event system. It is opt-out and it sends data to a Paperclip endpoint by default. Its paths are:
|
|
- `packages/shared/src/telemetry/`
|
|
- the generated contract `packages/shared/src/telemetry/generated/paperclip-telemetry.ts`
|
|
- each caller of `packages/shared/src/telemetry/events.ts` or `packages/shared/src/telemetry/client.ts`
|
|
- **Observability** is the OpenTelemetry trace path. An operator must set an OTLP endpoint. Until an operator sets the endpoint, the tracer is a no-operation. Its paths are:
|
|
- `server/src/instrumentation.ts`
|
|
- `doc/observability.md`
|
|
- `packages/adapter-utils/src/duplex-observability.ts`
|
|
- `server/src/services/duplex-observability-recorder.ts`
|
|
- the span attributes in `packages/adapter-utils/src/acpx-engine/startup-timing.ts`
|
|
- **The run log** holds rows in the local `heartbeat_run_events` table. The data stays in the instance database. Its paths are:
|
|
- `doc/run-log-events.md`
|
|
- `packages/db/src/schema/heartbeat_run_events.ts`
|
|
- the append path `appendRunEvent` in `server/src/services/heartbeat.ts`
|
|
|
|
Apply a review level that matches the path:
|
|
|
|
- **Telemetry change (strict review).** The author updates the generated contract first. The author updates `packages/shared/src/telemetry/README.md` in the same pull request. The author requests a privacy review. Reason: a Telemetry event goes to a Paperclip endpoint by default, so a mistake sends data immediately.
|
|
- **Observability change (lighter review).** The operator endpoint gate stays in place. The no-operation behaviour stays when no endpoint is set. A privacy review is not necessary while the change stays inside the closed span-attribute allowlist.
|
|
- **Run-log change (no extra review).** A run-log change needs neither review level above, because the data stays in the instance database.
|
|
|
|
**Exclusion.** The word "observability" in a file such as `server/src/services/recovery-observability.ts` names a different concept. Apply this rule by path, not by word match.
|
|
|
|
## 6. Database Change Workflow
|
|
|
|
When changing data model:
|
|
|
|
1. Edit `packages/db/src/schema/*.ts`
|
|
2. Ensure new tables are exported from `packages/db/src/schema/index.ts`
|
|
3. Generate migration:
|
|
|
|
```sh
|
|
pnpm db:generate
|
|
```
|
|
|
|
4. Validate compile:
|
|
|
|
```sh
|
|
pnpm -r typecheck
|
|
```
|
|
|
|
Notes:
|
|
- `packages/db/drizzle.config.ts` reads compiled schema from `dist/schema/*.js`
|
|
- `pnpm db:generate` compiles `packages/db` first
|
|
|
|
## 7. Verification Before Hand-off
|
|
|
|
[maps/feature-map/README.md](maps/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.
|
|
|
|
The sibling [agent access map](maps/agent-access-map/README.md) records APIs,
|
|
agent entry points and permission boundaries using the same capability IDs.
|
|
Follow [the feature-map scope rule](rules/feature-map-scope.mdc): additions require
|
|
substantial new features. Routine fixes, polish, refactors, and test changes do
|
|
not require map updates. Follow [the map contract](maps/README.md) for minimal
|
|
corrections when existing entries become materially inaccurate, and run
|
|
`node scripts/check-maps.mjs` after map edits.
|
|
Its structural checks do not prove live behavior or authorization.
|
|
|
|
Storybook has a downstream [feature catalog](maps/storybook-map/README.md).
|
|
Use `maintain-storybook` for story/fixture drift and `review-storybook` for browser
|
|
evidence. Keep the feature-map skills independent of this catalog. After story or recipe changes, update the affected source annotations or
|
|
recipe and run `node scripts/storybook-catalog.mjs`. Indexes are generated and
|
|
ignored; never commit aggregate catalogs, refresh review fingerprints, or append
|
|
a shared review journal. Use Git diffs and keep review evidence in the PR or issue.
|
|
Structural checks are not production acceptance.
|
|
|
|
Default local/agent verification path:
|
|
|
|
```sh
|
|
pnpm verify
|
|
```
|
|
|
|
This selects affected Vitest files with the same conservative dependency policy
|
|
as CI. It includes committed, staged, unstaged, and untracked changes against the
|
|
merge base with local `origin/master` (or `master`). Use `--base <ref>` for another
|
|
base and `--explain` to inspect the selection. Passing checks with complete input
|
|
graphs can be reused within this worktree. Opaque integration checks run fresh.
|
|
Source, test, fixture, configuration, dependency, environment, and toolchain changes
|
|
invalidate matching results. Failed or interrupted attempts are never passes.
|
|
|
|
Exit 2 means the change needs broader verification: run focused checks and let
|
|
required CI supply that coverage, or explicitly use `pnpm verify --full` for the
|
|
full local Vitest suite. Do not automatically follow exit 2 with a full local run.
|
|
Use `--no-cache` to request fresh execution without reading or saving passes.
|
|
`pnpm test` and `pnpm test:run` retain their full-suite behavior.
|
|
|
|
Browser suites stay opt-in:
|
|
|
|
```sh
|
|
pnpm test:e2e
|
|
pnpm test:release-smoke
|
|
```
|
|
|
|
Run the browser suites only when your change touches them or when you are explicitly verifying CI/release flows.
|
|
|
|
For normal issue work, run the smallest relevant verification first. Do not default to repo-wide typecheck/build/test on every heartbeat when a narrower check is enough to prove the change.
|
|
|
|
For a PR-ready handoff, run the relevant local checks and require the applicable
|
|
CI typecheck, build, and test checks to pass for the final tested revision. Record
|
|
their scope, revision, environment, and result links. Fresh CI can supply broad
|
|
coverage; do not duplicate a full local run merely to prepare a PR, resume a chat,
|
|
or repeat unchanged passing verification. A selected local pass does not replace
|
|
required CI, release qualification, browser acceptance, or a local/platform-specific
|
|
regression. After edits or a rebase, rerun affected checks and invalidate evidence
|
|
whose inputs or required coverage changed.
|
|
|
|
Use broad local checks when they resolve an actual remaining gap, such as a local
|
|
platform fault or explicit full-suite qualification:
|
|
|
|
```sh
|
|
pnpm -r typecheck
|
|
pnpm test:run
|
|
pnpm build
|
|
```
|
|
|
|
If memory is limited, use `node scripts/typecheck-low-memory.mjs` instead of `pnpm -r typecheck`. See `doc/DEVELOPING.md`.
|
|
|
|
If anything cannot be run, explicitly report what was not run and why.
|
|
|
|
## 8. API and Auth Expectations
|
|
|
|
- Base path: `/api`
|
|
- Board access is treated as full-control operator context
|
|
- Agent access uses bearer API keys (`agent_api_keys`), hashed at rest
|
|
- Agent keys must not access other companies
|
|
|
|
When adding endpoints:
|
|
|
|
- apply company access checks
|
|
- enforce actor permissions (board vs agent)
|
|
- write activity log entries for mutations
|
|
- return consistent HTTP errors (`400/401/403/404/409/422/500`)
|
|
|
|
## 9. UI Expectations
|
|
|
|
- Keep routes and nav aligned with available API surface
|
|
- Use company selection context for company-scoped pages
|
|
- Surface failures clearly; do not silently ignore API errors
|
|
- Form and wizard footers: keep Save & exit (or Cancel/Back) left and the primary action right in the same vertically aligned row. Each step owns the entire footer; never append Save & exit as a separate row. See `DESIGN.md`.
|
|
|
|
## 10. Pull Request Requirements
|
|
|
|
When creating a pull request (via `gh pr create` or any other method), you **must** read and fill in every section of [`.github/PULL_REQUEST_TEMPLATE.md`](.github/PULL_REQUEST_TEMPLATE.md). Do not craft ad-hoc PR bodies — use the template as the structure for your PR description. Required sections:
|
|
|
|
- **Thinking Path** — trace reasoning from project context to this change (see `CONTRIBUTING.md` for examples)
|
|
- **What Changed** — bullet list of concrete changes
|
|
- **Verification** — how a reviewer can confirm it works
|
|
- **Risks** — what could go wrong
|
|
- **Model Used** — the AI model that produced or assisted with the change (provider, exact model ID, context window, capabilities). Write "None — human-authored" if no AI was used.
|
|
- **Checklist** — all items checked
|
|
|
|
## 11. Definition of Done
|
|
|
|
A change is done when all are true:
|
|
|
|
1. Behavior matches `doc/SPEC-implementation.md`
|
|
2. Relevant local verification and required CI typecheck, test, and build checks pass for the final revision, with any acceptance or platform-specific gaps resolved
|
|
3. Contracts are synced across db/shared/server/ui
|
|
4. Docs updated when behavior or commands change
|
|
5. PR description follows the [PR template](.github/PULL_REQUEST_TEMPLATE.md) with all sections filled in (including Model Used)
|
|
|
|
## Design system
|
|
|
|
`DESIGN.md` at the repo root is the source of truth for UI design decisions. The token-only rule applies to all `ui/` changes: every color, spacing, radius, type, shadow, and motion value in `ui/src/components/**` and `ui/src/pages/**` comes from the token layer in `ui/src/index.css` — no hex, raw px, arbitrary Tailwind bracket values, or raw `font-size`/`fontSize` declarations in components, outside the documented allowlist in `ui/src/index.css`. Run `pnpm check:token-gates` (`scripts/check-token-gates.mjs`) before committing UI changes — it fails on any violation not covered by that allowlist.
|