diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 49fe962a8..000000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,30 +0,0 @@ -# ScriptCat — Copilot Instructions - -> **This file only holds Copilot-specific behavior and a router.** Architecture, coding conventions, commands, -> and testing mechanics are owned by [`../AGENTS.md`](../AGENTS.md) and the docs it routes to -> (`docs/develop.md`, `docs/architecture.md`, `docs/references/*`, `docs/verification.md`, `docs/design.md`, -> `docs/translation.md`). Read those before reviewing or writing code — don't rely on a second, separately -> maintained copy of them here; when this file and one of those docs disagree, the owning doc wins and this -> file should be corrected to match. - -## Code Review - -- Respond in Chinese when performing a code review (用中文回复代码审查意见). -- Conduct a **comprehensive and independent review** of the entire PR every time: - - **Full review every time** — review all modified files regardless of previous reviews or comments; treat - re-reviews as new, not relying on prior review state. - - **No skipping files** — examine every changed file regardless of type (`.md`, `.json`, `.yml`, `.toml`, - `.ts`, `.js`, `.py`, `.html`, `.css`, `.tsx`, `.vue`, `.sh`, etc.). - - **PR descriptions/commit messages/discussion are reference context only** — the review's conclusions must - be grounded in the actual code and file changes, inferring intent from the diff itself. - - **Independent verification** — don't assume an unchanged file or a previously reviewed section is safe; - verify code paths potentially affected by the current changes. - -## Minimal fallback (only if this surface can't reliably follow the link above) - -ScriptCat is a Manifest V3 browser extension (TypeScript + React 19 + Rspack, pnpm) that runs -Tampermonkey-compatible userscripts across five isolated contexts — Service Worker, Content, Inject, Offscreen, -Sandbox — communicating over `packages/message`. If you cannot load `AGENTS.md`, treat any architecture, -persistence-pattern, or service-shape claim you're tempted to state here as unverified, and prefer asking the -reviewer to confirm against `AGENTS.md` / `docs/architecture.md` over inventing a summary — this file is not -the source of truth for those facts and must not re-accumulate a parallel copy of them. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 120000 index 000000000..be77ac83a --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1 @@ +../AGENTS.md \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 8eb928f4d..082976722 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,49 +1,104 @@ # Repository Guidelines -This file provides guidance to AI coding agents (Claude Code, etc.) when working with code in this repository. -It holds only the engineering principles and the architecture quick-map; the concrete "how" belongs to the docs -below. `CLAUDE.md` merely `@import`s this file — don't split guidance between the two. Link the owning doc -instead of copying its content here. +This is the repo-wide contract for AI coding agents. It owns only engineering principles and the architecture +quick-map; concrete mechanics belong to the routed docs. Compatibility entry points reuse this file and have +no separate contract. Use [`docs/README.md`](docs/README.md) as the index and follow the owning doc instead of +duplicating its rules. -**Read before you act.** [`docs/README.md`](docs/README.md) indexes the full doc set. +## Route the task before acting | Before you… | Read | | --- | --- | -| write any code | [`docs/develop.md`](docs/develop.md) | -| build or modify any page, dialog, or block | [`docs/design.md`](docs/design.md) — its Core Constraints apply to *every* UI change, not only new pages | -| add or change localized content | [`docs/translation.md`](docs/translation.md) — plus the matching `docs/references/terminology-.md` when one exists | -| add, edit, reorganize, or review any tracked contributor Markdown (this file, `docs/*`, `.github/*.md`, package- and source-local READMEs) | [`docs/DOC-MAINTENANCE.md`](docs/DOC-MAINTENANCE.md) — *if you can't grep it on this branch, don't claim it* | +| write code | [`docs/develop.md`](docs/develop.md) | +| review code or a pull request | [`docs/develop.md`](docs/develop.md) + [`docs/pull-request.md`](docs/pull-request.md) for PR-body rules | +| change a process/message/service/persistence boundary or add a subsystem | [`docs/architecture.md`](docs/architecture.md) + the relevant `docs/references/architecture-*.md` | +| build or modify a page, dialog, or block | [`docs/design.md`](docs/design.md) — Core Constraints apply to every UI change | +| add or change localized content | [`docs/translation.md`](docs/translation.md) + matching `docs/references/terminology-.md` when present | +| add, edit, reorganize, or review tracked contributor Markdown (`AGENTS.md`, `docs/*`, `.github/*.md`, package/source-local READMEs) | [`docs/DOC-MAINTENANCE.md`](docs/DOC-MAINTENANCE.md) — if you can't grep it on this branch, don't claim it | | open or update a pull request | [`docs/pull-request.md`](docs/pull-request.md) | -| manually confirm a feature works | [`docs/verification.md`](docs/verification.md) — a throwaway scratch script against the built extension, not the committed suite | +| manually confirm a feature works | [`docs/verification.md`](docs/verification.md) — use a throwaway scratch script against the built extension, not the committed suite | + +For tasks matching multiple rows, read every applicable owner before that work; do not front-load unrelated +docs. For tasks matching none, inspect `docs/README.md` and nearby implementation/tests before inventing a rule +or abstraction. ## Project Overview -ScriptCat — Manifest V3 browser extension that runs Tampermonkey-compatible user scripts. TypeScript + React 19 + Rspack. Package manager is **pnpm** (preinstall enforces). The presentation layer (`src/pages/`) is **shadcn/ui + Tailwind CSS v4** (migrated from Arco Design + UnoCSS). +ScriptCat is a Manifest V3 browser extension for Tampermonkey-compatible user scripts, built with TypeScript, +React 19, and Rspack. **pnpm** is required by `preinstall`. The presentation layer (`src/pages/`) uses shadcn/ui +and Tailwind CSS v4 (migrated from Arco Design + UnoCSS). ## Engineering Principles -These are non-negotiable, regardless of what `docs/develop.md` says about mechanics — where a principle's scope -isn't universal, that's called out in the item itself. - -- **Fix root causes, not symptoms — refactor over patch.** No `as any` / `// @ts-ignore` / try-catch swallow / defensive skips to make errors disappear (宁愿重构也不要打补丁). If a test fails, fix the code, not the test — the narrow exceptions (a wrong test contract; a test that never carried value) are in [`docs/references/develop-testing.md`](docs/references/develop-testing.md#writing-meaningful-tests-what-to-clean-up--not-write). -- **Confirm before you fix.** Before touching a reported bug, reproduce it and confirm it actually exists — never fix from assumption. Capture the reproduction, then fix, **in that order** (确定 bug 存在 → 写测试或记录验证证据 → 修复); how to reproduce and what counts as capture are in [`docs/verification.md`](docs/verification.md) and the TDD entry below. -- **TDD/BDD first, for changes that alter observable behavior.** Write failing tests **before** implementing new or changed behavior, using BDD-style `describe`/`it` titles (Chinese or English). Two narrow exceptions — neither a blanket file/task category — are in [`docs/references/develop-testing.md`](docs/references/develop-testing.md#when-tdd-doesnt-apply). (Runner, mocks, and how to run tests are in `docs/develop.md`.) -- **SOLID, high cohesion & low coupling — applied to the existing extension points.** Persistence is a small backend taxonomy (`Repo` / `DAO` / `OPFSRepo` / a few custom repos), not one pattern to default to — pick by matching an existing entity with the same needs; see [`docs/references/architecture-data.md`](docs/references/architecture-data.md#adding-an-entity). For messages, use `Group.on(...)`. Not every service takes the same constructor shape — context services vs. the Agent subsystem differ; see [`docs/references/architecture-services.md`](docs/references/architecture-services.md#adding-a-service). Depend on narrow interfaces (`IMessageQueue`, not `MessageQueue`). -- **Direct replacement over adapter sandwiches.** When swapping a backend/library, replace in place — no `interface Foo + LegacyImpl + NewImpl` unless both must coexist at runtime. -- **Scope discipline — stay in your lane.** Bug fix ≠ cleanup PR. Touch only the files the task requires; leave unrelated files untouched (不要动和任务不相干的文件). Don't add helpers, abstractions, validation, or backwards-compat shims you don't need today. Three similar lines beats a premature abstraction. Don't remove or narrow currently supported behavior just to simplify a fix — only do so when the task or an already-verified contract explicitly calls for that change. This rule also governs test cleanup — [`docs/references/develop-testing.md`](docs/references/develop-testing.md#scope--cleanup-boundary) operationalizes it for tests, it does not carve out an exception. -- **No dead code or `// removed` markers** — git remembers. Delete unused code outright. -- **Comments explain "why", not "what".** Do not use ephemeral review labels such as `finding N` or review-round identifiers in comments or test names. Permanent issue or PR references are allowed when useful, but must supplement—not replace—the explanation. Do not restate code, duplicate enclosing documentation, or leave stale comments after code changes. See [`docs/develop.md`](docs/develop.md#comment-discipline) for the full policy. +These are repo-wide defaults. A linked, narrow exception in its owning doc is part of the contract; unrelated +downstream prose does not override it. + +- **Fix root causes, not symptoms — refactor over patch.** No `as any`, `// @ts-ignore`, swallowed errors, or + defensive skips or try-catch swallowing (宁愿重构也不要打补丁). When a test fails, fix the code rather than the test, except for a wrong + test contract or valueless test as defined in + [`docs/references/develop-testing.md`](docs/references/develop-testing.md#writing-meaningful-tests-what-to-clean-up--not-write). +- **Confirm before fixing.** Reproduce and confirm a reported bug before changing it; capture the reproduction + first (确定 bug 存在 → 写测试或记录验证证据 → 修复). Use [`docs/verification.md`](docs/verification.md) and + the TDD principle in this section for the evidence standard. +- **TDD/BDD first for observable behavior.** Write a failing `describe`/`it` test before implementation, with + Chinese or English titles. The two narrow, non-blanket exceptions are in + [`docs/references/develop-testing.md`](docs/references/develop-testing.md#when-tdd-doesnt-apply); runner, + mocks, and how to run tests are in [`docs/develop.md`](docs/develop.md). +- **SOLID, high cohesion, low coupling.** Match existing extension points: persistence uses the small + `Repo` / `DAO` / `OPFSRepo` / custom-repo taxonomy, matching an existing entity with the same needs; + messages use `Group.on(...)`; service constructor shapes differ by context and Agent subsystem; depend on + narrow interfaces such as `IMessageQueue`, not `MessageQueue`. See + [`docs/references/architecture-data.md`](docs/references/architecture-data.md#adding-an-entity), + [`docs/references/architecture-services.md`](docs/references/architecture-services.md#adding-a-service). +- **Direct replacement over adapter sandwiches.** Replace a backend/library in place; add + `interface Foo + LegacyImpl + NewImpl` only when both must coexist at runtime. +- **Scope discipline.** Bug fix ≠ cleanup PR: touch only required files (不要动和任务不相干的文件), add no unneeded + helpers/abstractions/validation/backwards-compat shims, and prefer three similar lines to a premature abstraction. + Do not remove or narrow supported + behavior for simplification unless the task or an already-verified contract explicitly calls for it. The same boundary applies to + test cleanup; see [`docs/references/develop-testing.md`](docs/references/develop-testing.md#scope--cleanup-boundary). +- **No dead code or `// removed` markers.** Delete unused code; git remembers. +- **Comments explain why.** Do not restate code, duplicate enclosing documentation, leave stale comments, or use + ephemeral review-round labels such as `finding N` in comments or test names. Permanent issue/PR references may + supplement, not replace, the explanation. See + [`docs/develop.md`](docs/develop.md#comment-discipline). + +## Decision and review discipline + +- **Separate authority from evidence.** A request or maintainer direction is execution authority within scope; + issues/PRs provide stated intent and context; source inspection, tests, browser runs, and integrations provide + observations; normative specifications, compatibility contracts, security policies, accepted contracts or oracles, and + maintainer decisions determine correctness. A request/issue/PR does not prove a bug, necessity, or correctness. + Label inferences, unverified, and contradicted claims. +- **State rationale before summary.** For material changes, connect problem/requirement → affected + scope/consequence → premise evidence → justification → remedy/trade-off → acceptance evidence → limitation/risk. + A diff shows what changed, not why. +- **Use the smallest justified semantic scope, not smallest diff.** A larger refactor is valid when it is the + smallest sound root-cause repair; do not call a solution minimal, best, or least risky without support. +- **Match claim strength to evidence.** Static reasoning, executed tests, browser runs, and external integrations + prove different scopes. A negative claim needs the relevant channel observed through its closure window or a + causal proof that the side effect cannot occur. +- **Bound readiness.** Do not call a material change review-ready with failed acceptance, a critical contradiction + or evidence gap, unjustified scope, or stale final-patch evidence. A requested draft/investigation may proceed + when labeled; report the blocker and clearing condition. +- **Review semantic and physical coverage.** Inspect every changed file and affected path. Map material semantic + families to representatives, disposition, highest-risk seam, and residual risk; separate confidence from + completeness. On re-review, bind the current head and reconcile findings as present, resolved, narrowed, stale, + or new. +- **Require a witness and impact for findings.** Report only a concrete trigger/proof path, material consequence, + useful location, and actionable contract to restore; do not turn an unverified repository assumption into a + finding. ## Architecture -Quick map only — the internals guide and its "how to extend" recipes are in -[`docs/architecture.md`](docs/architecture.md). +Use [`docs/architecture.md`](docs/architecture.md) and its referenced deep-dives before changing a boundary or +adding a subsystem. This section is orientation, not an implementation manual. ### Multi-Process Model -5 isolated contexts communicating via message passing: +5 isolated contexts communicate by message passing: -``` +```text Service Worker (src/service_worker.ts) ├── ExtensionMessage ──────────────→ Content Script (src/content.ts) │ └── CustomEventMessage ──→ Inject Script (src/inject.ts) @@ -55,28 +110,59 @@ Service Worker (src/service_worker.ts) > `EventPageOffscreenManager` on Firefox MV3; Offscreen replies to SW over `ExtensionMessage`. `WindowMessage` > is the Offscreen ↔ Sandbox channel. -- **Service Worker** — central hub: script CRUD, chrome APIs, permission verification, resource caching, message routing -- **Content** — bridges SW and inject script -- **Inject** — runs in page context with `unsafeWindow` -- **Offscreen** — DOM-capable background environment for background/scheduled scripts -- **Sandbox** — isolated execution via `with(arguments[0])`; cron scheduling +- **Service Worker** — central hub for script CRUD, Chrome APIs, permission verification, resource caching, and message routing. +- **Content** — bridges SW and inject script. +- **Inject** — runs in page context with `unsafeWindow`. +- **Offscreen** — DOM-capable background environment for background/scheduled scripts. +- **Sandbox** — isolated execution via `with(arguments[0])`; cron scheduling. -Execution paths: page scripts → `chrome.userScripts`; background → SW → Offscreen → Sandbox; scheduled → cron in Sandbox. +Execution paths: page scripts → `chrome.userScripts`; background → SW → Offscreen → Sandbox; scheduled → cron in +Sandbox. ### Message Passing (`packages/message/`) -`ExtensionMessage` (chrome.runtime — SW ↔ Content / Inject / Offscreen), `WindowMessage` (postMessage — Offscreen ↔ Sandbox), `ServiceWorkerMessageSend` (`clients.matchAll()` + `postMessage` — SW → Offscreen on Chrome), `CustomEventMessage` (CustomEvent — Content ↔ Inject), `MessageQueue` (cross-context broadcast). + +`ExtensionMessage` (chrome.runtime — SW ↔ Content / Inject / Offscreen), `WindowMessage` (postMessage — Offscreen ↔ +Sandbox), `ServiceWorkerMessageSend` (`clients.matchAll()` + `postMessage` — SW → Offscreen on Chrome), +`CustomEventMessage` (CustomEvent — Content ↔ Inject), and `MessageQueue` (cross-context broadcast). ### Service & Data Layers -- Services live under `src/app/service/` as **context services** (`content/`, `offscreen/`, `sandbox/`, `service_worker/`) plus **cross-cutting subsystems** (`agent/`, `extension/`, `queue.ts`) — not one uniform shape. Details, inventory, "adding a service": [`docs/references/architecture-services.md`](docs/references/architecture-services.md). -- Persistence is a backend taxonomy (`Repo` / `DAO` / `OPFSRepo` / custom), not one pattern. Details, inventory, "adding an entity": [`docs/references/architecture-data.md`](docs/references/architecture-data.md). -- **GM API** split across content / SW / offscreen, each a `GMApi`; values via `ValueService`. Adding a new GM API: [`docs/references/architecture-gm-api.md`](docs/references/architecture-gm-api.md). -- **Agent subsystem** (`src/app/service/agent/`) is an AI-agent layer spanning the existing five contexts, not a sixth. Full write-up: [`docs/references/architecture-agent.md`](docs/references/architecture-agent.md). + +- Services live under `src/app/service/` as context services (`content/`, `offscreen/`, `sandbox/`, + `service_worker/`) plus cross-cutting subsystems (`agent/`, `extension/`, `queue.ts`), not one uniform shape. See + [`docs/references/architecture-services.md`](docs/references/architecture-services.md#adding-a-service) for inventory and adding services. +- Persistence is a backend taxonomy (`Repo` / `DAO` / `OPFSRepo` / custom), not one default pattern. See + [`docs/references/architecture-data.md`](docs/references/architecture-data.md#adding-an-entity) for inventory and adding entities. +- **GM API** is split across content / SW / offscreen, each with a `GMApi`; values use `ValueService`. See + [`docs/references/architecture-gm-api.md`](docs/references/architecture-gm-api.md) for additions. +- **Agent subsystem** (`src/app/service/agent/`) is an AI-agent layer spanning the five contexts, not a sixth. See + [`docs/references/architecture-agent.md`](docs/references/architecture-agent.md). ### Browser Extension APIs (MV3) -`chrome.userScripts` (page injection), Offscreen API (DOM in background), Declarative Net Request (intercepts `.user.js` URLs to trigger install flow). -### Key Packages +`chrome.userScripts` (page injection), Offscreen API (DOM in background), and Declarative Net Request (intercepts +`.user.js` URLs to trigger installation). -`message/` (with mocks), `filesystem/` (WebDAV, cloud drive providers, zip export — see [`docs/cloud-sync.md`](docs/cloud-sync.md)), `cloudscript/`, `eslint/` (userscript lint config — `eslint-plugin-userscripts`-based `defaultConfig` for the in-app editor), `chrome-extension-mock/`. +### Key Packages -The project's *own* custom ESLint rules live in `eslint-rules/` at the repo root, **not** in `packages/eslint/`; both are documented in [`docs/develop.md`](docs/develop.md#eslint-custom-rules). +`message/` (with mocks), `filesystem/` (WebDAV, cloud-drive providers, ZIP export; see +[`docs/cloud-sync.md`](docs/cloud-sync.md)), `cloudscript/`, `eslint/` (userscript lint config based on +`eslint-plugin-userscripts` and `defaultConfig` for the in-app editor), and `chrome-extension-mock/`. The project's own custom ESLint +rules live in root `eslint-rules/`, not `packages/eslint/`; both are documented in +[`docs/develop.md`](docs/develop.md#eslint-custom-rules). + +## Completion checksum + +Before claiming completion, use the applicable owner docs to check the final state. This is a handoff checklist, not +a second copy of their mechanics; when details matter, linked owners win. If a check cannot be completed, state the +limitation instead of claiming “verified” or “all fixed” without evidence. + +- **Owners/facts.** Every task part follows its routed owner; changed documentation follows + [`docs/DOC-MAINTENANCE.md`](docs/DOC-MAINTENANCE.md), including branch-aware fact checks against committed + code, not memory or untracked files. +- **Evidence/verification.** Reproduction, tests, manual evidence, and the applicable rules in + [`docs/references/develop-testing.md`](docs/references/develop-testing.md) and [`docs/verification.md`](docs/verification.md) + support the claim, including any explicit exception; run required checks and report blockers or tooling limits. +- **Contract/scope.** The final diff matches the requested or verified behavior, contains no unrelated cleanup or + compatibility layer, and preserves scope discipline. +- **Architecture.** Boundary-sensitive work was checked against [`docs/architecture.md`](docs/architecture.md) and + the relevant deep-dive rather than inventing a parallel abstraction. diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 43c994c2d..000000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 000000000..47dc3e3d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/docs/DOC-MAINTENANCE.md b/docs/DOC-MAINTENANCE.md index ecfa661f8..46a2deee5 100644 --- a/docs/DOC-MAINTENANCE.md +++ b/docs/DOC-MAINTENANCE.md @@ -88,7 +88,7 @@ of sanitization patterns can otherwise look like matches — so don't rely on a | Doc | Owns | | --- | --- | -| [`../AGENTS.md`](../AGENTS.md) | Engineering principles + architecture quick-map. `CLAUDE.md` only `@import`s it. | +| [`../AGENTS.md`](../AGENTS.md) | Engineering principles, architecture quick-map, and shared agent contract. `CLAUDE.md` and other compatibility entry points are symlink aliases; they do not own a separate policy. | | [`develop.md`](./develop.md) | The concrete "how": commands, structure, style, i18n, commit/PR. Testing → [`references/develop-testing.md`](./references/develop-testing.md). | | [`pull-request.md`](./pull-request.md) | The PR body: structure and evidence rules. The human-facing template stays lightweight. | | [`design.md`](./design.md) | The design system; tokens, component palette, and layout/motion/state/a11y patterns → the three `references/design-*.md`. | @@ -99,7 +99,6 @@ of sanitization patterns can otherwise look like matches — so don't rely on a | [`translation.md`](./translation.md) | Translation / localization single source of truth. | | [`DOC-MAINTENANCE.md`](./DOC-MAINTENANCE.md) | This guide: organization rules, fact-check / anti-drift discipline, policy-consistency checks — across every tracked contributor Markdown, not just `AGENTS.md` + `docs/*`. | | [`README.md`](./README.md) | The reader-facing index: what each doc contains and when to read it. | -| `.github/copilot-instructions.md` | Copilot-specific entry point and genuine tool-specific differences only; shared facts route to the owning doc above instead of being copied. | | Package-local `README.md` (e.g. `packages/message/README.md`, `packages/filesystem/README.md`) | That package's purpose, boundaries, entry points, and local gotchas — not a duplicate of repo-wide architecture or coding policy. | This table records **ownership boundaries** — which doc a given fact belongs in. It is deliberately *not* the @@ -177,7 +176,11 @@ git ls-files '*.md' | while IFS= read -r doc; do # references/verification-report-template.md's screenshot/resource examples, verification.md's # "Evidence location" spans) aren't false-flagged as broken sed '/^```/,/^```/d; /^~~~/,/^~~~/d' "$doc" | sed -E 's/`[^`]*`//g' | grep -oE '\]\(([^)]+)\)' | sed -E 's/^\]\(|\)$//g' | grep -vE '^(https?:|mailto:|#|app:)' | while IFS= read -r link; do - target="$(dirname "$doc")/${link%%#*}" + link_doc="$doc" + if [ -L "$doc" ]; then + link_doc="$(dirname "$doc")/$(readlink "$doc")" + fi + target="$(dirname "$link_doc")/${link%%#*}" [ -e "$target" ] && echo "ok $doc → $link" || echo "BROKEN $doc → $link" done done @@ -197,9 +200,13 @@ a heading — an external deep link into that heading breaks if you rename it wi ## When you find a discrepancy -Fix the **doc** to match the code — the code on this branch is the source of truth. The exception: if the code -itself is wrong (a real bug), fix the code and say so in the PR. Either way, never silently drop a check you -couldn't satisfy — surface it in the PR description so a reviewer can confirm. +Fix the **doc** to match the code for descriptive facts about the current branch — the code on this branch is +the source of truth for names, paths, and current implementation shape. Normative intended behavior may instead +be owned by a specification, compatibility contract, security policy, accepted test oracle, or maintainer +decision. When those sources conflict with the current code, surface the conflict and resolve it with the owning +authority; do not silently rewrite either side to make the patch easier. If the code itself is wrong, fix the code +and say so in the PR. Either way, never silently drop a check you couldn't satisfy — surface it in the PR +description so a reviewer can confirm. ## Honest completion claims diff --git a/docs/README.md b/docs/README.md index f34c011f5..5b4fc35cf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ | 文档 | 说明 | | --- | --- | -| [`../AGENTS.md`](../AGENTS.md) | 工程原则、架构速览、AI/贡献者约定的单一信息源 —— 但仅相对 `CLAUDE.md`(其仅导入它)成立;`.github/copilot-instructions.md` 是 Copilot 的独立入口,与本文件共享的事实需在两边都改动时做一致性核对(parity review)。 | +| [`../AGENTS.md`](../AGENTS.md) | 工程原则、架构速览与 AI coding agent 的共享约定所有者;`CLAUDE.md` 与其他兼容入口均通过符号链接复用它,不维护副本。 | | [`develop.md`](./develop.md) | 开发规范:命令、目录结构、编码风格、UI/主题、i18n、提交/PR 流程;测试设计/清理口径与运行机制(含 Vitest 性能)拆到 [`references/develop-testing.md`](./references/develop-testing.md)。**写代码前先读。** | | [`pull-request.md`](./pull-request.md) | PR 描述指南:代理与贡献者使用的详细章节、按变更类型取舍规则、验证与审查信息要求。 | | [`design.md`](./design.md) | 设计系统参考:主题机制、shadcn 组件选型、新建页面配方总览;令牌完整值拆到 [`references/design-tokens.md`](./references/design-tokens.md),组件清单拆到 [`references/design-components.md`](./references/design-components.md),布局/响应式/动效/状态/无障碍范式拆到 [`references/design-patterns.md`](./references/design-patterns.md)。**做页面/对话框/区块前先读。** | diff --git a/docs/pull-request.md b/docs/pull-request.md index 3ef4475d7..870222532 100644 --- a/docs/pull-request.md +++ b/docs/pull-request.md @@ -60,6 +60,54 @@ For a normal feature or behavior change, use the following sections when they ar Small documentation, dependency, or CI changes may use a shorter description and omit sections that do not apply, but must still explain what changed and what was checked. For visual changes, retain the template's screenshot section and provide the relevant evidence. Never claim a test, review, screenshot, or recording that did not happen. Leave `Code reviewed by human` unchecked unless a human has actually reviewed the PR — the same applies to any other checklist item: leave it unchecked (without rewording it) whether the work wasn't done or doesn't apply. If an item doesn't apply to this PR, add a brief `N/A — ` note below the checklist, so reviewers can tell "not applicable" from "not done" — an unchecked box alone doesn't distinguish the two. +The brief `N/A` note above is only for an inapplicable PR checklist item. Test dimensions remain applicability-gated by [the testing guide](./references/develop-testing.md) and are omitted when they do not apply; do not add a formal applicability table or proof packet to a PR. + +## Decision, evidence, and readiness + +For a material behavior, configuration, security, performance, compatibility, persistence, migration, release, or refactor change, write enough context for a reviewer to reconstruct: + +1. the problem or requirement; +2. the affected scope and consequence; +3. the evidence that the premise is real; +4. why action is justified; +5. the selected remedy and material trade-off; +6. acceptance evidence; and +7. the remaining limitation or risk. + +Keep this chain proportional. A confirmed one-line correction or a small documentation fix needs only the material parts; a non-trivial design choice should explain why doing nothing or a plausible smaller alternative was not selected and what would reopen the decision. + +Keep these roles separate: + +- maintainer direction authorizes execution within the requested scope; +- an issue, PR description, or discussion supplies stated intent and scope context; +- source inspection, tests, browser runs, and integrations provide observations; +- a specification, compatibility contract, security policy, accepted test oracle, or maintainer decision owns normative correctness. + +An issue or PR does not by itself prove that a bug exists, that a remedy is necessary, that a change is correct, or that external publication or residual-risk acceptance is authorized. + +Consider risk for every material change. Use an explicit limitation or rollback paragraph when the change affects shared APIs, persistence, permissions, security/privacy, browser compatibility, cross-context messaging, asynchronous lifecycle, or release/build behavior. Identify residual risk and the decision owner; do not claim that a significant residual risk has been accepted without that owner's decision. + +An agent must not present a change as review-ready when a material acceptance condition fails, a critical claim is unverified or contradicted, the diff exceeds the justified scope, required verification is missing without an adequate substitute, a known correctness/security/privacy/compatibility defect remains, or the description no longer matches the final patch. An explicitly requested draft or investigation may still be submitted when labeled as such. Report the blocker, the evidence, and the condition that would clear it. + +Verification claims bind to a revision or clearly identified worktree. If code, configuration, generated artifacts, or a decision-relevant description changes after a check, rerun every affected check before claiming readiness. A final commit SHA is sufficient identity for ordinary GitHub work; a cryptographic evidence ledger is not required by default. + +## Evidence triggered by changed contract + +Activate only the rows touched by the actual change; mixed changes use their union. + +| Changed contract | Extra evidence to expect | +| --- | --- | +| Bug fix | Before reproducer, expected behavior, regression test or justified manual evidence, and the same reproducer after the fix | +| New behavior | User/system need, observable acceptance criteria, and compatibility/scope boundaries | +| Refactor | Concrete structural problem and evidence that behavior/public contracts are preserved | +| Performance/resource | Baseline, workload, environment, method, before/after result, and accepted correctness/complexity trade-off | +| Security/privacy/permissions | Protected boundary, threat or failure mode, safe verification, residual risk, and private reporting when appropriate | +| Dependency/build/configuration | Compatibility or lifecycle reason, version/platform scope, lock/generated rationale, and build verification | +| Documentation/tests only | The authoritative behavior or decision being corrected or preserved; verify claims, links, or tests without inventing runtime evidence | +| Generated/mechanical | Source input, tool/command, reason for regeneration, and evidence that unrelated semantic edits were not mixed in | +| Persistence/migration/release | Compatibility and data scope, ordering/irreversibility, rollback/restore path, and rehearsal or invariant evidence where safe | +| Async/concurrency/stateful UI | Duplicate in-flight work, stale or late results, cancellation/retry, cleanup, and identity or generation ordering where applicable | + ## Review-oriented content For non-trivial changes, make the description useful for review: diff --git a/docs/verification.md b/docs/verification.md index 1002fb866..83857c65e 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -296,6 +296,14 @@ before assertions). which in `report.md`; never dress up a red run as green. - Never weaken an assertion or skip a check to make a scratch run "pass". +### Evidence scope and negative claims + +Name the evidence type behind each material conclusion. Source or static reasoning proves only what follows from the inspected source and contract; an executed unit or fixture proves its scenario; browser runtime evidence proves the observed browser scenario; an external integration observation proves that integration run. Do not promote one evidence type into a broader claim without additional support. + +When claiming that something did **not** happen — such as a request, write, disclosure, duplicate event, or stale callback — either observe the forbidden channel through the relevant completion or closure window, or provide a causal proof that execution cannot reach that side effect. An error callback, missing success callback, final UI value, or final persisted value alone is insufficient. + +For a negative claim, `holds` requires that closure-window observation or causal proof. Otherwise report `not observed`, preserving the per-claim verdicts above; this rule does not replace them. + ## Maintaining this guide When the workflow or the paths in it change, keep this doc true to the branch (see diff --git a/scripts/check-issue-templates.test.mjs b/scripts/check-issue-templates.test.mjs index b2b1f5145..28be8d58d 100644 --- a/scripts/check-issue-templates.test.mjs +++ b/scripts/check-issue-templates.test.mjs @@ -81,7 +81,8 @@ describe("issue 模板机械检查", () => { expect(problemsOf(makeFixtureRoot())).toEqual([]); }); - it("仓库现有的 issue 模板应全部通过检查", () => { + // 该用例会读取整个 src 并解析 issues/new 链接,冷缓存或 worker 并发时可能超过 fast 项目的 340ms 预算。 + it("仓库现有的 issue 模板应全部通过检查", { timeout: 850 }, () => { expect(problemsOf(REPO_ROOT)).toEqual([]); });