Files
PaperClipAI/maps/README.md
T
DottaandClaude Opus 5.5 9b21dcbdda refactor: remove SPEC docs and repoint spec citations (#20565)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Contributors and agents read the docs under `doc/` before they
change code
> - `doc/SPEC.md` and `doc/SPEC-implementation.md` were out of date.
`doc/SPEC-implementation.md` became an append-only log: in 60 days it
got about 1,645 new lines and lost 181, across 140 commits
> - #20557 changed `AGENTS.md` so the code and its tests are the source
of truth, and the specs are only background
> - This pull request removes the two spec docs. It moves only the
sections that live code comments cite into focused docs, and it repoints
all other references
> - The benefit is one less stale document that agents read and append
to

## Linked Issues or Issue Description

Refs #20557 (merged). This PR is the follow-up that removes the docs. It
is based on `master`, which already contains #20557.

**Issue type**
Outdated content. The docs are out of date and conflict with the code.

**Where is the issue?**
`doc/SPEC.md`, `doc/SPEC-implementation.md`, and the code comments and
docs that cite them.

**What's wrong?**
`doc/SPEC.md` and `doc/SPEC-implementation.md` are out of date, but
agents still read them and append a paragraph with each fix.

**Suggested fix**
Delete both files. Move the sections that code cites into focused docs.
Repoint the references.

## What Changed

- Deleted `doc/SPEC.md` and `doc/SPEC-implementation.md`.
- Moved these spec sections, because live code comments cite them:
- §9.3.1 "Shared default-open issue writes" → new section in
`doc/agent-permission-defaults.md`.
- §9.8.1 "Issue-thread interaction resolver contract" →
`doc/execution-semantics.md`, "Issue-thread interaction resolution".
That section already had most of the contract. I added only the missing
parts: the `supersedeOnUserComment` default, the canonical policy list,
the addressee and cap rules, the rule that surfaces show the server's
effective audience, and the cross-issue budget charge. The short policy
summary at the top of the section now points to the list, so the
definitions occur one time only.
- §9.9 "Task Watchdog Authority Contract" → new "Authority contract"
section in `doc/TASK-WATCHDOG.md`. It holds the allowed and disallowed
mutation lists and the deferred capabilities. The atomic recovery batch,
restoration verification, and interaction rules were already in
`doc/execution-semantics.md` §11, so the new section links there and
does not repeat them. I did not move the "Downstream acceptance
criteria" checklist or the sentence about the CTO and Security sign-off.
These were implementation-time notes; the tests now hold that coverage.
- §9.10 "Company Skill Policy Contract" → new
`doc/company-skill-policy.md`. No focused doc had this contract. I did
not move the "Required regression tests" phase checklist.
- Did not move any other part of the specs.
- Repointed code comments that cited spec sections:
- `packages/shared/src/issue-write-denial.ts` (§9.3) →
`doc/agent-permission-defaults.md`
- `server/src/routes/issues.ts` (§9.9) → `doc/TASK-WATCHDOG.md`,
"Authority contract"
- `server/src/routes/issues.ts` (§9.3, §9.8.1 cross-issue budget) →
`doc/agent-permission-defaults.md`
- `ui/src/lib/interaction-audience.ts` and
`ui/src/components/InteractionGovernancePanel.tsx` (§9.8.1) →
`doc/execution-semantics.md`
- `ui/src/lib/skill-policy-denial.ts`, `ui/src/pages/CompanySkills.tsx`,
`ui/src/pages/CompanySkills.production.tsx`,
`ui/src/pages/SkillStudio.tsx` (§9.10) → `doc/company-skill-policy.md`
- `server/src/services/recovery/ownership-invariant-report.ts` (monitor
deadline wait path) → `doc/execution-semantics.md` §8. That section
already lists the one-shot monitor as a valid wait path.
- Resynced the git blob pin for
`packages/shared/src/issue-write-denial.ts` in
`tests/runner-e2e/source-sdk-public-inputs.json`. The comment edit
changed the file's hash, and the Runner support suite checks that pin. I
used `node tests/runner-e2e/source-sdk-public-inputs.mjs <HEAD>
--write`; only that one pin changed.
- Updated `AGENTS.md` §1 so it does not name the deleted files.
- Removed the links to the deleted files from
`doc/plugins/PLUGIN_SPEC.md`.
- Updated the `doc-maintenance` agent skill
(`.agents/skills/doc-maintenance/`) so it no longer audits or stages
`doc/SPEC.md`.
- Removed or replaced references in `maps/README.md`,
`maps/feature-map/README.md`, `maps/storybook-map/README.md`,
`doc/PRODUCT.md`, `doc/CLIPHUB.md`, `doc/DEPLOYMENT-MODES.md`,
`doc/DEVELOPING.md`, `doc/evals.md`, `doc/spec/agent-runs.md`,
`doc/AGENTCOMPANIES_SPEC_INVENTORY.md`,
`doc/connections/CONNECTOR-PLAYBOOK.md`,
`doc/plugins/ideas-from-opencode.md`, `doc/execution-semantics.md`,
`doc/TASK-WATCHDOG.md`, and `.devin/wiki.json`.
- In `doc/execution-semantics.md`, the "admission is independent of
cleanup and accounting" reference now states the rule inline: only a
hard stop, an explicit pause, or an inactive company refuses admission.
- Kept these references as they are: dated plans in `doc/plans/` and
`docs/plans/`, the dated log
`doc/logs/2026-05-24-cli-api-parity-e2e-log.md`, `releases/`, the
transcript fixture `ui/src/fixtures/runTranscriptFixtures.ts` (it uses
the filename only as sample text), and
`docs/specs/external-task-protocol.md` (it refers to the Symphony
project's own `SPEC.md`).

## Verification

- `git grep -n "SPEC-implementation\|SPEC\.md"` (without `releases/`,
and ignoring `PLUGIN_SPEC.md` citations) finds only the kept references
listed above.
- `grep -rn "§9\.\(3\|8\|9\|10\)" ui/src server/src packages/shared/src`
finds no results.
- `node scripts/check-maps.mjs`: "Maps aligned: 35 areas, 192 capability
IDs".
- `pnpm check:token-gates`: "All gates clean".
- `pnpm exec vitest run --config tests/runner-e2e/vitest.config.ts
tests/runner-e2e/source-sdk-public-type.test.ts
tests/runner-e2e/source-sdk-evidence.test.ts`: 45 passed. These failed
in CI before the pin resync.
- `pnpm verify`: exit 2 ("Broader verification required") because
`AGENTS.md` is a global CI input. Required CI supplies the broad
coverage for this revision.
- All code changes are comments only. No runtime behavior changes. The
title uses `refactor:` because comments in source files changed.

## Risks

- Low risk. The change removes docs and edits comments only.
- A reader can lose context from spec sections that I did not move. The
text stays in git history. The code and its tests are the source of
truth.
- External links to the two deleted files will return 404.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Opus 5.5 (`claude-opus-5-5`), in Claude Code with
tool use (shell, file edits). Standard context window.

## 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 (focused checks above; CI
supplies broad coverage)
- [x] I have added or updated tests where applicable (not applicable:
docs and comments only)
- [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
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 13:07:59 -06:00

195 lines
11 KiB
Markdown

# Paperclip maps
The maps describe the same capabilities from two perspectives:
- [Feature map](feature-map/README.md): what a person can do, where to reach it,
and how to verify the user journey. Preserve its Poteto format.
- [Agent access map](agent-access-map/README.md): the APIs and agent entry points
for those capabilities, their permission boundaries, and access verification.
The [chat scenario catalog](../tests/runner-e2e/chat-scenarios/README.md) adds
natural-language requests, starting context and expected conversational outcomes
for the same capability IDs. It lives with Product E2E as planning data; a scenario
reference is neither a registered execution nor evidence that a journey passed.
These are sibling directories under `maps/`. Each feature file has a same-named
agent access companion. Reuse the product map's sub-feature IDs, so `tasks/create`
identifies the same capability in both maps. Product behavior remains governed by
the code and its tests; a map cannot grant authority or redefine a permission
denial as success.
## Capability identifiers
The feature ID is the recipe filename without `.md`, such as `onboarding`.
The full capability ID joins that feature ID and a Sub-features key with `/`:
the `company` key in `feature-map/onboarding.md` is `onboarding/company`.
Its `agent-access-map/onboarding.md` companion uses the same local `company` key.
[The feature-map index](feature-map/README.md#browse-features) lists the existing
feature and full capability IDs.
Each child page states ``Feature ID: `onboarding`.`` after its introduction or
product-map link. In feature recipes, show the full ID beside the parsed local
key: ``- `company`: `onboarding/company` — create a company``. In access
companions and Storybook verification guidance, keep the existing local heading
and put ``Capability ID: `onboarding/company`.`` beneath it. These labels make
the existing identifiers visible without changing keys, anchors, or ID generation.
Use full capability IDs in cross-feature references, Storybook annotations,
tests, issues, PRs, and verification evidence. Both segments use lowercase
letters, digits, and hyphens. Keep filenames and keys stable when display titles
or navigation labels change; renaming either changes the capability ID.
Entry-point IDs describe a surface, such as `web-wizard`, and are scoped to their
recipe. Reference them with a recipe link, such as
[onboarding.md#web-wizard](feature-map/onboarding.md#web-wizard), and record the
capability exercised separately. Navigation section labels are not capability IDs.
See [IDs and references](feature-map/README.md#ids-and-references) for examples.
## Access contract
Every business operation needs both an API and a usable agent entry point for an
actor authorized to perform it. A dedicated tool is optional when REST, the CLI,
an assigned MCP client, or native `search_api` / `call_api` already provides the
operation. Record which agent surfaces actually have that path; an installed CLI
or optional MCP package cannot be assumed available to every native/remote run.
Track these independently:
| Dimension | Values and meaning |
| --- | --- |
| API | `present`, `missing`, `not-applicable`, or `unreviewed`. Use exact methods/paths; distinguish protocols from REST. |
| Agent access | `available`, `partial`, `missing`, `restricted`, `operator-only`, `not-applicable`, or `unreviewed`. Name the supported surface and actual entry point. |
| Policy | Actor, action/grant, company/resource/ownership scope, responsible-user intersection, run requirements, work modes, and gates relevant to the operation. |
| Evidence | `source-only`, `verified`, `failed`, `blocked`, or `not-run`. Source presence and successful board calls are not agent verification. |
| Review depth | `baseline` records representative operations and known gaps; `operation-reviewed` enumerates the capability's meaningful operations and their individual access contracts. |
Broad capabilities such as task properties must be split into operations before
they count as operation-reviewed: renaming, metadata edits, assignment,
dependencies, and lifecycle changes can use different tools and permission rules.
An available read path cannot certify a write path. List/get/create/update/delete,
execution/control, credential handling, and resolution are separate where their
authority or transport differs. Do not duplicate request schemas from OpenAPI.
### Exceptions and restrictions
Presentation-only state, static developer fixtures, and pre-start/local operator
work may use `not-applicable` for a domain API, with a concrete reason and the
existing local path. When a capability combines shared data with presentation,
split the operations: browser recents do not exempt resource lookup from API
coverage. Promoting local state to a shared feature requires revisiting the entry.
A board-only endpoint is `restricted` for agent identity, not an automatic
exception or a missing API. Cite the enforced policy and record whether the
agent can request the authorized human's action and observe its result. An
unresolved delegation question remains in **Gaps**. Company access, a job title,
a personal assistant's OAuth grant, or an accepted interaction does not grant
board identity. Keep budget, approval, secret and execution authority intact.
Check actual route/service authorization and production tool admission. OpenAPI
actor labels and scenario/evaluation tool declarations are supporting metadata;
record disagreements rather than using them as proof of access. Native API
fallback restrictions, tool field/scope limits, and rollout settings are part of
the agent path, even when a legacy agent can call the REST endpoint directly.
## Companion file format
Each `agent-access-map/<area>.md` has an H1, a relative link to its product file,
and its feature ID, followed by one H2 backticked local key per product
sub-feature. Each capability starts with its full capability ID and contains
these fields:
- **Review:** `baseline` or `operation-reviewed`.
- **API:** presence state and exact operation IDs, or a reasoned exception.
- **Agent access:** availability state and concrete entry points by surface.
- **Policy:** relevant permission and runtime boundaries, with source references.
- **Evidence:** evidence state, reviewed commit and sources or executed proof.
- **Verification:** allowed/denied assertions and observable result; record what
has actually run separately from the proposed recipe.
- **Gaps:** missing APIs/paths, discovery drift, unreviewed operations or policy
decisions; use `none` only for the enumerated scope that was reviewed.
For an operation-reviewed capability, use H3 backticked operation IDs and repeat
API, Agent access, Policy, Evidence, Verification and Gaps for each operation.
Use small operation names such as `create`, `update`, `read`, or `run-now`.
The enclosing capability has `Review: operation-reviewed` only after its
meaningful operations have been enumerated. The following excerpt shows one
operation; include the others before using that review label:
```markdown
## `definition`
Review: `operation-reviewed`.
### `create`
API: `present` — POST /api/companies/{companyId}/routines.
Agent access: `available` — agent REST, CLI routine create and native call_api
under the enabled rollout and active-run/mode gates.
Policy: same company; assigneeAgentId must be the calling agent; cite the
routine authorization and native API policy sources.
Evidence: `source-only` — reviewed commit and source links; no live proof.
Verification: `not-run` — create an owned routine; reject assignment to another
agent; inspect saved configuration, attribution and retry behavior.
Gaps: verify ownership and responsible-user resolution with a permitted agent
context; source presence alone does not qualify this operation.
```
## Keeping the maps synchronized
Add entries only for substantial new features under the
[feature-map scope rule](../rules/feature-map-scope.mdc). Routine fixes, polish,
refactors, performance work, and test changes do not require map updates. Correct
or remove existing text only when behavior or access changes make it materially
inaccurate; keep the correction local to the affected recipe or companion.
Preserve IDs across renames where the
capability is unchanged; update the affected cross-links together. Indexes discover recipes automatically. An API-only
change may update the companion without rewriting unchanged user instructions.
Update the corresponding chat scenarios when their request, assumptions or
expected outcome changes; use multiple cases for meaningfully different starting
conditions rather than treating an API path as conversational coverage.
[maintain-verification-skill](../.agents/skills/maintain-verification-skill/SKILL.md)
owns reconciliation of both maps. It follows changed source and authorization,
checks real agent reachability, and records product gaps without implementing
them during a maintenance pass. The creation skill uses this structure.
[verify-paperclip](../.agents/skills/verify-paperclip/SKILL.md) consumes the relevant
recipes and reports evidence/drift; map editing belongs to maintenance.
Run the structural check after map changes:
```sh
node scripts/check-maps.mjs
```
It checks paired areas/IDs, navigation metadata, required fields, and local references. It
does not certify endpoint authorization, production bindings, operation
completeness, or live behavior. Source audits must check those against the
existing API and tool contracts; avoid a second schema catalog or runtime.
For live access proof, use Paperclip's existing API/runner/MCP fixtures or an owned
isolated instance. Use the actual agent identity, target and work mode. Assert the
allowed result and relevant denial (another company/private resource, wrong
owner, missing grant, invalid run, restricted mode or resolver). Mutations also
need persisted state/attribution and retry behavior. Capture evidence using the
[existing artifact workflow](../doc/AGENT-ARTIFACTS.md); keep executed run results
separate from generated `maps/generated/coverage.json`, which lists page references.
## Local authorship and generated indexes
Change only the recipes, access contracts and stories whose behavior or intent
changed. Feature recipes own navigation metadata; stories own small
`parameters.paperclip` annotations. Keep the feature-map README's readable ID
index aligned with those sources; it does not register entries for generation.
Do not refresh counts in shared READMEs, inventories, fingerprints or review
journals.
`node scripts/storybook-catalog.mjs` validates and generates aggregate navigation,
Storybook data, verification routes and the page inventory. All outputs live in
ignored `maps/generated/`, `ui/storybook/generated/`, and the ignored Storybook
`preview.tsx` wrapper. Start/build and UI typechecking generate their own inputs.
A clean merged checkout therefore assembles both branches' changes automatically.
Git provides history and diffs. PRs, issues and CI artifacts retain review/run
evidence for the named revision. Capability associations do not create whole-file
review dependencies. Keep durable scenario limits in the affected recipe or story.