# dnd - Doramagic AI Context Pack

> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。

## 充分原则

- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。
- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。

## 给宿主 AI 的使用方式

你正在读取 Doramagic 为 dnd 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。

## Claim 消费规则

- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。
- **事实最低状态**：`supported`
- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。
- `weak`：只能作为低置信度线索，必须要求用户继续核实。
- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。
- `unverified`：不得作为事实使用，应明确说证据不足。
- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。

## 它最适合谁

- **想在安装前理解开源项目价值和边界的用户**：当前证据主要来自项目文档。 证据：`README.md` Claim：`clm_0002` supported 0.86

## 它能做什么

- **项目知识预览**（可做安装前预览）：项目可被阅读和解释，但当前证据不足以确认可安装能力或运行入口。 证据：`README.md`, `package.json`, `CONTRIBUTING.md`, `LICENSE` 等 Claim：`clm_0001` supported 0.86

## 怎么开始

- 项目证据中没有稳定 Quick Start 命令；此项应留空，而不是由 Doramagic 编造。

## 继续前判断卡

- **当前建议**：先做 Prompt Preview
- **为什么**：当前信息足以做安装前体验，但真实兼容性、输出质量或风险边界还不能直接相信。

### 30 秒判断

- **现在怎么做**：先做 Prompt Preview
- **最小安全下一步**：先跑 Prompt Preview
- **先别相信**：真实输出质量不能在安装前相信。
- **继续会触碰**：宿主 AI 上下文

### 现在可以相信

- **适合人群线索：想在安装前理解开源项目价值和边界的用户**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **能力存在：项目知识预览**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md`, `package.json`, `CONTRIBUTING.md`, `LICENSE` 等 Claim：`clm_0001` supported 0.86

### 现在还不能相信

- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。
- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。
- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。
- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。
- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。
- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。

### 继续会触碰什么

- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

- 解释项目适合谁和能做什么
- 基于项目文档演示典型对话流程
- 帮助用户判断是否值得安装或继续研究

## 哪些必须安装后验证

- 真实安装 Skill、插件或 CLI
- 执行脚本、修改本地文件或访问外部服务
- 验证真实输出质量、性能和兼容性

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0003` inferred 0.45
- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。
- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。

## 开工前工作上下文

### 加载顺序

- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。
- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。
- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。
- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。
- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。

### 任务路由

- **项目知识预览**：先基于 role_skill_index / evidence_index 帮用户挑选可用角色、Skill 或工作流。 边界：可做安装前 Prompt 体验。 证据：`README.md`, `package.json`, `CONTRIBUTING.md`, `LICENSE` 等 Claim：`clm_0001` supported 0.86

### 上下文规模

- 文件总数：671
- 重要文件覆盖：40/671
- 证据索引条目：64
- 角色 / Skill 条目：5

### 证据不足时的处理

- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。
- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。
- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。
- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。

## Prompt Recipes

### 适配判断

- 目标：判断这个项目是否适合用户当前任务。
- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。

```text
请基于 dnd 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。
```

### 安装前体验

- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。
- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。

```text
请把 dnd 当作安装前体验资产，而不是已安装工具或真实运行环境。

请严格输出四段：
1. 先问我 3 个必要问题。
2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。
3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。
4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。

硬性边界：
- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。
- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。
- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。
- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。
- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。
- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。

```

### 角色 / Skill 选择

- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。
- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。

```text
请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。
```

### 风险预检

- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。
- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。

```text
请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。
```

### 宿主 AI 开工指令

- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。
- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。

```text
请基于 dnd 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```

## 角色 / Skill 索引

- 共索引 5 个角色 / Skill / 项目文档条目。

- **Core characteristics**（project_doc）：Beautiful and accessible drag and drop for lists with React https://facebook.github.io/react/ 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **Contributing**（project_doc）：Thanks for considering contributing to @hello-pangea/dnd ! ❤️ 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CONTRIBUTING.md`
- **Changelog**（project_doc）：chore: update release-it configuration 1afeefe https://github.com/hello-pangea/dnd/commit/1afeefe chore dev-deps : update bump all non-major development dependencies 604b93d https://github.com/hello-pangea/dnd/commit/604b93d 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CHANGELOG.md`
- **Contributor Covenant Code of Conduct**（project_doc）：Contributor Covenant Code of Conduct 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CODE_OF_CONDUCT.md`
- **Security Policy**（project_doc）：IMPORTANT: DO NOT DISCLOSE SECURITY-RELATED ISSUES PUBLICLY. SEE REPORTING INSTRUCTIONS BELOW reporting-a-vulnerability . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`SECURITY.md`

## 证据索引

- 共索引 64 条证据。

- **Core characteristics**（documentation）：Beautiful and accessible drag and drop for lists with React https://facebook.github.io/react/ 证据：`README.md`
- **Package**（package_manifest）：{ "name": "@hello-pangea/dnd", "version": "18.0.1", "private": false, "description": "Beautiful and accessible drag and drop for lists with React", "author": "Alex Reardon ", "maintainers": "Gabriel Santerre ", "Reece Carolan " , "keywords": "drag and drop", "dnd", "sortable", "reorder", "reorderable", "react", "react.js", "natural", "beautiful", "accessible" , "repository": { "type": "git", "url": "https://github.com/hello-pangea/dnd.git" }, "bugs": { "url": "https://github.com/hello-pangea/dnd/issues" }, "main": "dist/dnd.cjs.js", "module": "dist/dnd.esm.js", "types": "dist/dnd.d.ts", "sideEffects": false, "files": "/dist", "/src" , "publishConfig": { "access": "public" }, "config": { "pr… 证据：`package.json`
- **Contributing**（documentation）：Thanks for considering contributing to @hello-pangea/dnd ! ❤️ 证据：`CONTRIBUTING.md`
- **License**（source_file）：Licensed under the Apache License, Version 2.0 the "License" ; you may not use this file except in compliance with the License. You may obtain a copy of the License at 证据：`LICENSE`
- **Invariant**（source_file）：export class RbdInvariant extends Error ⋮---- export function invariant condition: false, message?: string : never; export function invariant condition: any, message?: string : asserts condition; export function invariant condition: unknown, message?: string, : asserts condition 证据：`src/invariant.ts`
- **Lib Types**（source_file）：export type RecursivePartial = { P in keyof T ?: T P extends infer U ? RecursivePartial : T P extends ...args: any = any ? T P undefined : T P extends object ? RecursivePartial : T P ; }; 证据：`src/lib-types.ts`
- **Types**（source_file）：import type { BoxModel, Rect, Position } from 'css-box-model'; export type Id = TId; export type DraggableId = Id ; export type DroppableId = Id ; export type TypeId = Id ; export type ContextId = Id ; export type ElementId = Id ; export type DroppableMode = 'standard' 'virtual'; export interface DroppableDescriptor { id: DroppableId ; type: TypeId ; mode: DroppableMode; } export interface DraggableDescriptor { id: DraggableId ; index: number; droppableId: DroppableId ; type: TypeId ; } export interface DraggableOptions { canDragInteractiveElements: boolean; shouldRespectForcePress: boolean; isEnabled: boolean; } export type Direction = 'horizontal' 'vertical'; export interface VerticalAxis… 证据：`src/types.ts`
- **Action Creators**（source_file）：import type { Position } from 'css-box-model'; import type { Critical, DraggableId, DroppableId, CompletedDrag, MovementMode, Viewport, DimensionMap, DropReason, Published, } from '../types'; type ActionTypes = Action 'type' ; type ExtractAction = Extract ; export function guard action: unknown, predicate: TActionType, : action is ExtractAction export interface BeforeInitialCaptureArgs { draggableId: DraggableId; movementMode: MovementMode; } export interface BeforeInitialCaptureAction { type: 'BEFORE INITIAL CAPTURE'; payload: BeforeInitialCaptureArgs; } export type BeforeInitialCaptureActionCreator = typeof beforeInitialCapture; export const beforeInitialCapture = args: BeforeInitialCaptu… 证据：`src/state/action-creators.ts`
- **Auto Scroller Types**（source_file）：import type { State, DraggingState } from '../../types'; export interface AutoScroller { start: state: DraggingState = void; stop: = void; scroll: state: State = void; } 证据：`src/state/auto-scroller/auto-scroller-types.ts`
- **Auto Scroller Options Types**（source_file）：import { RecursivePartial } from '../../../lib-types'; export interface AutoScrollerOptions { startFromPercentage: number; maxScrollAtPercentage: number; maxPixelScroll: number; ease: percentage: number = number; durationDampening: { stopDampeningAt: number; accelerateAt: number; }; disabled: boolean; } export type PartialAutoScrollerOptions = RecursivePartial ; 证据：`src/state/auto-scroller/fluid-scroller/auto-scroller-options-types.ts`
- **Index**（source_file）：import type { Rect, Spacing } from 'css-box-model'; import getDistanceThresholds from './get-distance-thresholds'; import { AutoScrollerOptions } from '../../auto-scroller-options-types'; import type { DistanceThresholds } from './get-distance-thresholds'; import type { Axis } from '../../../../../types'; import getValue from './get-value'; interface GetOnAxisArgs { container: Rect; distanceToEdges: Spacing; dragStartTime: number; axis: Axis; shouldUseTimeDampening: boolean; getAutoScrollerOptions: = AutoScrollerOptions; } 证据：`src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/index.ts`
- **Index**（source_file）：import type { Position, Rect, Spacing } from 'css-box-model'; import { apply, isEqual, origin } from '../../../position'; import getScrollOnAxis from './get-scroll-on-axis'; import adjustForSizeLimits from './adjust-for-size-limits'; import { horizontal, vertical } from '../../../axis'; import { AutoScrollerOptions } from '../auto-scroller-options-types'; ⋮---- interface Args { dragStartTime: number; container: Rect; subject: Rect; center: Position; shouldUseTimeDampening: boolean; getAutoScrollerOptions: = AutoScrollerOptions; } 证据：`src/state/auto-scroller/fluid-scroller/get-scroll/index.ts`
- **Index**（source_file）：import rafSchd from 'raf-schd'; import type { Position } from 'css-box-model'; import type { DraggingState, DroppableId } from '../../../types'; import scroll from './scroll'; import { invariant } from '../../../invariant'; ⋮---- import { AutoScrollerOptions } from './auto-scroller-options-types'; import { defaultAutoScrollerOptions } from './config'; export interface PublicArgs { scrollWindow: change: Position = void; scrollDroppable: id: DroppableId, change: Position = void; getAutoScrollerOptions?: = AutoScrollerOptions; } export interface FluidScroller { scroll: state: DraggingState = void; start: state: DraggingState = void; stop: = void; } interface WhileDragging { dragStartTime: numb… 证据：`src/state/auto-scroller/fluid-scroller/index.ts`
- **Index**（source_file）：import type { Position } from 'css-box-model'; import createFluidScroller from './fluid-scroller'; import type { FluidScroller } from './fluid-scroller'; import createJumpScroller from './jump-scroller'; import type { JumpScroller } from './jump-scroller'; import type { AutoScroller } from './auto-scroller-types'; import type { DroppableId, State } from '../../types'; import type { MoveArgs } from '../action-creators'; import { AutoScrollerOptions } from './fluid-scroller/auto-scroller-options-types'; export interface Args { scrollWindow: offset: Position = void; scrollDroppable: id: DroppableId, change: Position = void; move: args: MoveArgs = unknown; getAutoScrollerOptions: = AutoScroller… 证据：`src/state/auto-scroller/index.ts`
- **Dimension Marshal Types**（source_file）：import type { Position } from 'css-box-model'; import type { CollectionStartingActionCreator, PublishWhileDraggingActionCreator, UpdateDroppableScrollActionCreator, UpdateDroppableIsEnabledActionCreator, UpdateDroppableIsCombineEnabledActionCreator, } from '../action-creators'; import type { DroppableId, Critical, DimensionMap, LiftRequest, Viewport, } from '../../types'; export interface StartPublishingResult { critical: Critical; dimensions: DimensionMap; viewport: Viewport; } export interface DimensionMarshal { updateDroppableIsEnabled: id: DroppableId, isEnabled: boolean = void; updateDroppableIsCombineEnabled: id: DroppableId, isEnabled: boolean, = void; updateDroppableScroll: id: Drop… 证据：`src/state/dimension-marshal/dimension-marshal-types.ts`
- **Is Home Of**（source_file）：import type { DraggableDimension, DroppableDimension } from '../../types'; 证据：`src/state/droppable/is-home-of.ts`
- **Should Use Placeholder**（source_file）：import type { DraggableDescriptor, DragImpact } from '../../types'; import whatIsDraggedOver from './what-is-dragged-over'; 证据：`src/state/droppable/should-use-placeholder.ts`
- **Index**（source_file）：import type { Position } from 'css-box-model'; import type { DroppableDimension, Viewport, DragImpact, DraggableDimension, DraggableDimensionMap, LiftEffect, } from '../../../types'; import getPageBorderBoxCenterFromImpact from '../get-page-border-box-center'; import getClientFromPageBorderBoxCenter from './get-client-from-page-border-box-center'; interface Args { impact: DragImpact; draggable: DraggableDimension; droppable: DroppableDimension; draggables: DraggableDimensionMap; viewport: Viewport; afterCritical: LiftEffect; } 证据：`src/state/get-center-from-impact/get-client-border-box-center/index.ts`
- **Index**（source_file）：import type { Position } from 'css-box-model'; import type { DragImpact, DraggableDimension, DroppableDimension, DraggableDimensionMap, ImpactLocation, LiftEffect, } from '../../../types'; import whenCombining from './when-combining'; import whenReordering from './when-reordering'; import withDroppableDisplacement from '../../with-scroll-change/with-droppable-displacement'; interface Args { impact: DragImpact; afterCritical: LiftEffect; draggable: DraggableDimension; droppable: DroppableDimension null; draggables: DraggableDimensionMap; } const getResultWithoutDroppableDisplacement = { impact, draggable, droppable, draggables, afterCritical, }: Args : Position = 证据：`src/state/get-center-from-impact/get-page-border-box-center/index.ts`
- **Index**（source_file）：import type { Position, Rect } from 'css-box-model'; import type { DroppableId, DraggableDimension, DroppableDimension, DraggableDimensionMap, DroppableDimensionMap, DragImpact, Viewport, LiftEffect, } from '../../types'; import getDroppableOver from '../get-droppable-over'; import getDraggablesInsideDroppable from '../get-draggables-inside-droppable'; import withDroppableScroll from '../with-scroll-change/with-droppable-scroll'; import getReorderImpact from './get-reorder-impact'; import getCombineImpact from './get-combine-impact'; import noImpact from '../no-impact'; import { offsetRectByPosition } from '../rect'; interface Args { pageOffset: Position; draggable: DraggableDimension; drag… 证据：`src/state/get-drag-impact/index.ts`
- **Get Home Location**（source_file）：import type { DraggableDescriptor, DraggableLocation } from '../types'; 证据：`src/state/get-home-location.ts`
- **Auto Scroll**（source_file）：import { invariant } from '../../invariant'; import type { AutoScroller } from '../auto-scroller/auto-scroller-types'; import type { Middleware } from '../store-types'; import { guard } from '../action-creators'; import type { State } from '../../types'; const shouldStop = action: unknown 证据：`src/state/middleware/auto-scroll.ts`
- **Drop Middleware**（source_file）：import type { Position } from 'css-box-model'; import { invariant } from '../../../invariant'; import type { State, DropReason, Critical, DraggableLocation, DropResult, CompletedDrag, Combine, DimensionMap, DraggableDimension, } from '../../../types'; import type { Middleware } from '../../store-types'; import { animateDrop, completeDrop, dropPending, guard, } from '../../action-creators'; import type { AnimateDropArgs } from '../../action-creators'; import { isEqual } from '../../position'; import getDropDuration from './get-drop-duration'; import getNewHomeClientOffset from './get-new-home-client-offset'; import getDropImpact from './get-drop-impact'; import type { Result } from './get-dr… 证据：`src/state/middleware/drop/drop-middleware.ts`
- **Lift**（source_file）：import { invariant } from '../../invariant'; import type { DimensionMarshal } from '../dimension-marshal/dimension-marshal-types'; import type { State, ScrollOptions, LiftRequest } from '../../types'; import type { Middleware } from '../store-types'; import { completeDrop, initialPublish, flush, beforeInitialCapture, guard, } from '../action-creators'; import validateDimensions from './util/validate-dimensions'; 证据：`src/state/middleware/lift.ts`
- **Index**（source_file）：import type { Position } from 'css-box-model'; import type { PublicResult } from './move-in-direction-types'; import type { DroppableId, DraggingState, Direction, DroppableDimension, DraggableDimension, DroppableDimensionMap, DragImpact, } from '../../types'; import moveToNextPlace from './move-to-next-place'; import moveCrossAxis from './move-cross-axis'; import whatIsDraggedOver from '../droppable/what-is-dragged-over'; interface Args { state: DraggingState; type: 'MOVE UP' 'MOVE RIGHT' 'MOVE DOWN' 'MOVE LEFT'; } const getDroppableOver = impact: DragImpact, droppables: DroppableDimensionMap, : DroppableDimension null = 证据：`src/state/move-in-direction/index.ts`
- **Index**（source_file）：import type { Position } from 'css-box-model'; import type { PublicResult } from '../move-in-direction-types'; import type { DroppableDimension, DraggableDimension, DraggableDimensionMap, DroppableDimensionMap, DragImpact, Viewport, LiftEffect, } from '../../../types'; import getBestCrossAxisDroppable from './get-best-cross-axis-droppable'; import getClosestDraggable from './get-closest-draggable'; import getDraggablesInsideDroppable from '../../get-draggables-inside-droppable'; import getClientFromPageBorderBoxCenter from '../../get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center'; import getPageBorderBoxCenter from '../../get-center-from-impact/get-p… 证据：`src/state/move-in-direction/move-cross-axis/index.ts`
- **Move In Direction Types**（source_file）：import type { Position } from 'css-box-model'; import type { DragImpact } from '../../types'; export interface PublicResult { clientSelection: Position; impact: DragImpact; scrollJumpRequest: Position null; } 证据：`src/state/move-in-direction/move-in-direction-types.ts`
- **Index**（source_file）：import type { Position } from 'css-box-model'; import type { DroppableDimension, DraggableDimension, DraggableDimensionMap, DragImpact, Viewport, LiftEffect, } from '../../../types'; import type { PublicResult } from '../move-in-direction-types'; import getDraggablesInsideDroppable from '../../get-draggables-inside-droppable'; import moveToNextCombine from './move-to-next-combine'; import moveToNextIndex from './move-to-next-index'; import isHomeOf from '../../droppable/is-home-of'; import getPageBorderBoxCenter from '../../get-center-from-impact/get-page-border-box-center'; import speculativelyIncrease from '../../update-displacement-visibility/speculatively-increase'; import getClientFrom… 证据：`src/state/move-in-direction/move-to-next-place/index.ts`
- **Index**（source_file）：import { invariant } from '../../../../invariant'; import type { DraggableDimension, DroppableDimension, DragImpact, CombineImpact, DraggableLocation, DraggableId, } from '../../../../types'; import { tryGetDestination } from '../../../get-impact-location'; import removeDraggableFromList from '../../../remove-draggable-from-list'; export interface Args { isMovingForward: boolean; draggable: DraggableDimension; destination: DroppableDimension; insideDestination: DraggableDimension ; previousImpact: DragImpact; } ⋮---- function getImpact target: DraggableId 证据：`src/state/move-in-direction/move-to-next-place/move-to-next-combine/index.ts`
- **Index**（source_file）：import { invariant } from '../../../../invariant'; import type { DraggableDimension, DroppableDimension, DraggableDimensionMap, DragImpact, LiftEffect, Viewport, ImpactLocation, } from '../../../../types'; import calculateReorderImpact from '../../../calculate-drag-impact/calculate-reorder-impact'; import fromCombine from './from-combine'; import fromReorder from './from-reorder'; export interface Args { isMovingForward: boolean; isInHomeList: boolean; draggable: DraggableDimension; draggables: DraggableDimensionMap; destination: DroppableDimension; insideDestination: DraggableDimension ; previousImpact: DragImpact; viewport: Viewport; afterCritical: LiftEffect; } 证据：`src/state/move-in-direction/move-to-next-place/move-to-next-index/index.ts`
- **Index**（source_file）：import type { DimensionMap, DraggingState, CollectingState, DropPendingState, Published, DraggableId, DraggableDimension, DroppableDimensionMap, DraggableDimensionMap, DroppableDimension, DragImpact, DroppablePublish, DroppableId, } from '../../types'; ⋮---- import getDragImpact from '../get-drag-impact'; import adjustAdditionsForScrollChanges from './adjust-additions-for-scroll-changes'; import { toDraggableMap, toDroppableMap } from '../dimension-structures'; import getLiftEffect from '../get-lift-effect'; import scrollDroppable from '../droppable/scroll-droppable'; import whatIsDraggedOver from '../droppable/what-is-dragged-over'; interface Args { state: CollectingState DropPendingState;… 证据：`src/state/publish-while-dragging-in-virtual/index.ts`
- **Registry Types**（source_file）：import type { Position } from 'css-box-model'; import type { Id, DraggableId, DraggableDescriptor, DraggableOptions, DraggableDimension, DroppableId, ScrollOptions, DroppableDescriptor, DroppableDimension, TypeId, } from '../../types'; export type GetDraggableDimensionFn = windowScroll: Position, = DraggableDimension; export interface DraggableEntry { uniqueId: Id; descriptor: DraggableDescriptor; options: DraggableOptions; getDimension: GetDraggableDimensionFn; } export interface DraggableAPI { register: entry: DraggableEntry = void; update: entry: DraggableEntry, last: DraggableEntry = void; unregister: entry: DraggableEntry = void; exists: id: DraggableId = boolean; getById: id: Draggabl… 证据：`src/state/registry/registry-types.ts`
- **Store Types**（source_file）：import type { Store as ReduxStore, Dispatch as ReduxDispatch } from 'redux'; import type { Action } from './action-creators'; import type { State } from '../types'; ⋮---- export type Dispatch = ReduxDispatch ; export type Store = ReduxStore ; export interface MiddlewareStore { dispatch: Dispatch; getState : State; } ⋮---- getState : State; ⋮---- export interface Middleware { api: MiddlewareStore, : next: action: unknown = unknown = action: unknown = unknown; } 证据：`src/state/store-types.ts`
- **Check Doctype**（source_file）：import { warning } from '../../dev-warning'; 证据：`src/view/drag-drop-context/check-doctype.ts`
- **Check React Version**（source_file）：import { invariant } from '../../invariant'; import { warning } from '../../dev-warning'; interface Version { major: number; minor: number; patch: number; raw: string; } ⋮---- const getVersion = value: string : Version = const isSatisfied = expected: Version, actual: Version : boolean = 证据：`src/view/drag-drop-context/check-react-version.ts`
- **Drag Drop Context Types**（source_file）：export interface AppCallbacks { isDragging: = boolean; tryAbort: = void; } export type SetAppCallbacks = callbacks: AppCallbacks = void; 证据：`src/view/drag-drop-context/drag-drop-context-types.ts`
- **Drag Drop Context**（source_file）：import React from 'react'; import type { ReactNode } from 'react'; import type { Responders, ContextId, Sensor } from '../../types'; import ErrorBoundary from './error-boundary'; import preset from '../../screen-reader-message-preset'; import App from './app'; import useUniqueContextId from './use-unique-context-id'; import { PartialAutoScrollerOptions } from '../../state/auto-scroller/fluid-scroller/auto-scroller-options-types'; export interface DragDropContextProps extends Responders { children: ReactNode null; dragHandleUsageInstructions?: string; enableDefaultSensors?: boolean null; nonce?: string; sensors?: Sensor ; autoScrollerOptions?: PartialAutoScrollerOptions; } export default fun… 证据：`src/view/drag-drop-context/drag-drop-context.tsx`
- **Draggable Types**（source_file）：import type { Position } from 'css-box-model'; import type { ReactNode, DragEventHandler, TransitionEventHandler, } from 'react'; import type { DraggableId, DroppableId, DraggableDimension, State, MovementMode, ContextId, ElementId, DraggableRubric, } from '../../types'; import { dropAnimationFinished } from '../../state/action-creators'; export interface DraggingStyle { position: 'fixed'; top: number; left: number; boxSizing: 'border-box'; width: number; height: number; transition: string; transform?: string; zIndex: number; opacity?: number; pointerEvents: 'none'; } export interface NotDraggingStyle { transform?: string; transition?: 'none'; } export type DraggableStyle = DraggingStyle No… 证据：`src/view/draggable/draggable-types.ts`
- **Draggable**（source_file）：import React, { useRef, DragEvent, TransitionEvent } from 'react'; import { flushSync } from 'react-dom'; import { useMemo, useCallback } from '../../use-memo-one'; import type { DraggableRubric, DraggableDescriptor } from '../../types'; import getStyle from './get-style'; import useDraggablePublisher from '../use-draggable-publisher/use-draggable-publisher'; import type { Args as PublisherArgs } from '../use-draggable-publisher/use-draggable-publisher'; import AppContext from '../context/app-context'; import DroppableContext from '../context/droppable-context'; import type { Props, DraggableProvided, DraggableStyle, DraggableProvidedDragHandleProps, } from './draggable-types'; import { use… 证据：`src/view/draggable/draggable.tsx`
- **Droppable Types**（source_file）：import type { ReactNode } from 'react'; import type { DraggableId, DroppableId, TypeId, Direction, Placeholder, State, ContextId, DraggableRubric, DroppableMode, } from '../../types'; import type { DraggableChildrenFn } from '../draggable/draggable-types'; import { updateViewportMaxScroll } from '../../state/action-creators'; ⋮---- export interface DroppableProvidedProps { 'data-rfd-droppable-context-id': ContextId; 'data-rfd-droppable-id': DroppableId; } export interface DroppableProvided { innerRef: a?: HTMLElement null = void; placeholder: ReactNode null; droppableProps: DroppableProvidedProps; } export interface UseClone { dragging: DraggableRubric; render: DraggableChildrenFn; } export… 证据：`src/view/droppable/droppable-types.ts`
- **Droppable**（source_file）：import ReactDOM from 'react-dom'; import React, { useRef, useContext, FunctionComponent } from 'react'; import type { ReactNode } from 'react'; import { useMemo, useCallback } from '../../use-memo-one'; import { invariant } from '../../invariant'; import type { DraggableId } from '../../types'; import type { Props, DroppableProvided } from './droppable-types'; import useDroppablePublisher from '../use-droppable-publisher'; import Placeholder from '../placeholder'; import AppContext from '../context/app-context'; import type { AppContextValue } from '../context/app-context'; import DroppableContext from '../context/droppable-context'; import type { DroppableContextValue } from '../context/dr… 证据：`src/view/droppable/droppable.tsx`
- **Event Types**（source_file）：import type { Position } from 'css-box-model'; import { BeforeCapture } from '../../types'; export interface EventOptions { passive?: boolean; capture?: boolean; once?: boolean; } export interface EventBinding { eventName: string; fn: event: TEvent = void; options?: EventOptions; } interface BeforeEventDetail { before: BeforeCapture; clientSelection: Position; } export type AnimationEventBinding = EventBinding ; export type BeforeCaptureEvent = EventBinding ; export type ClipboardEventBinding = EventBinding ; export type CompositionEventBinding = EventBinding ; export type DragEventBinding = EventBinding ; export type ErrorEventBinding = EventBinding ; export type FocusEventBinding = EventB… 证据：`src/view/event-bindings/event-types.ts`
- **Placeholder Types**（source_file）：export interface PlaceholderStyle { display: string; boxSizing: 'border-box'; width: number; height: number; marginTop: number; marginRight: number; marginBottom: number; marginLeft: number; flexShrink: '0'; flexGrow: '0'; pointerEvents: 'none'; transition: string; } 证据：`src/view/placeholder/placeholder-types.ts`
- **Focus Marshal Types**（source_file）：import type { DraggableId } from '../../types'; export type Unregister = = void; export type Register = id: DraggableId, focus: = void = Unregister; export interface FocusMarshal { register: Register; tryRecordFocus: tryRecordFor: DraggableId = void; tryRestoreFocusRecorded: = void; tryShiftRecord: previous: DraggableId, redirectTo: DraggableId = void; } 证据：`src/view/use-focus-marshal/focus-marshal-types.ts`
- **Closest**（source_file）：function closestPonyfill el: Element null, selector: string : null Element export default function closest el: Element, selector: string : Element null 证据：`src/view/use-sensor-marshal/closest.ts`
- **Use Keyboard Sensor**（source_file）：import { useRef } from 'react'; import { useMemo, useCallback } from '../../../use-memo-one'; import { invariant } from '../../../invariant'; import type { SensorAPI, PreDragActions, SnapDragActions, DraggableId, } from '../../../types'; import type { KeyboardEventBinding, AnyEventBinding, EventOptions, } from '../../event-bindings/event-types'; ⋮---- import bindEvents from '../../event-bindings/bind-events'; import preventStandardKeyEvents from './util/prevent-standard-key-events'; import supportedPageVisibilityEventName from './util/supported-page-visibility-event-name'; import useLayoutEffect from '../../use-isomorphic-layout-effect'; function noop interface KeyMap { key: number : true;… 证据：`src/view/use-sensor-marshal/sensors/use-keyboard-sensor.ts`
- **Use Mouse Sensor**（source_file）：import { useRef } from 'react'; import type { Position } from 'css-box-model'; import { useCallback, useMemo } from '../../../use-memo-one'; import { invariant } from '../../../invariant'; import type { PreDragActions, FluidDragActions, DraggableId, SensorAPI, DraggableOptions, } from '../../../types'; import type { AnyEventBinding, EventBinding, EventOptions, MouseEventBinding, } from '../../event-bindings/event-types'; import bindEvents from '../../event-bindings/bind-events'; ⋮---- import preventStandardKeyEvents from './util/prevent-standard-key-events'; import supportedPageVisibilityEventName from './util/supported-page-visibility-event-name'; import useLayoutEffect from '../../use-iso… 证据：`src/view/use-sensor-marshal/sensors/use-mouse-sensor.ts`
- **Use Touch Sensor**（source_file）：import { useRef } from 'react'; import type { Position } from 'css-box-model'; import { useCallback, useMemo } from '../../../use-memo-one'; import { invariant } from '../../../invariant'; import type { DraggableId, SensorAPI, PreDragActions, FluidDragActions, } from '../../../types'; import type { AnyEventBinding, EventOptions, TouchEventBinding, } from '../../event-bindings/event-types'; import bindEvents from '../../event-bindings/bind-events'; ⋮---- import supportedPageVisibilityEventName from './util/supported-page-visibility-event-name'; import { noop } from '../../../empty'; import useLayoutEffect from '../../use-isomorphic-layout-effect'; type TouchWithForce = Touch & { force: numbe… 证据：`src/view/use-sensor-marshal/sensors/use-touch-sensor.ts`
- **Prevent Standard Key Events**（source_file）：interface KeyMap { key: number : true; } 证据：`src/view/use-sensor-marshal/sensors/util/prevent-standard-key-events.ts`
- **Use Sensor Marshal**（source_file）：import rafSchd from 'raf-schd'; import { useState } from 'react'; import type { Position } from 'css-box-model'; import { useCallback, useMemo } from '../../use-memo-one'; import { invariant } from '../../invariant'; import type { ContextId, State, Sensor, StopDragOptions, PreDragActions, FluidDragActions, SnapDragActions, DraggableId, SensorAPI, TryGetLock, TryGetLockOptions, DraggableOptions, } from '../../types'; import create from './lock'; import type { Lock, LockAPI } from './lock'; import type { Store, Action } from '../../state/store-types'; import canStartDrag from '../../state/can-start-drag'; import { move as moveAction, moveUp as moveUpAction, moveRight as moveRightAction, moveD… 证据：`src/view/use-sensor-marshal/use-sensor-marshal.ts`
- **Use Validate Sensor Hooks**（source_file）：import { invariant } from '../../invariant'; import type { Sensor } from '../../types'; import usePreviousRef from '../use-previous-ref'; import useDevSetupWarning from '../use-dev-setup-warning'; import useDev from '../use-dev'; export default function useValidateSensorHooks sensorHooks: Sensor 证据：`src/view/use-sensor-marshal/use-validate-sensor-hooks.ts`
- **Style Marshal Types**（source_file）：import type { DropReason } from '../../types'; export interface StyleMarshal { dragging: = void; dropping: reason: DropReason = void; resting: = void; } 证据：`src/view/use-style-marshal/style-marshal-types.ts`
- **Get Window Scroll**（source_file）：import type { Position } from 'css-box-model'; 证据：`src/view/window/get-window-scroll.ts`
- **Customize Autoscroll App**（source_file）：import React, { ReactElement, useState } from 'react'; import styled from '@emotion/styled'; import { DropResult } from '../../../src/types'; import DragDropContext from '../../../src/view/drag-drop-context'; import { PartialAutoScrollerOptions } from '../../../src/state/auto-scroller/fluid-scroller/auto-scroller-options-types'; import reorder from '../reorder'; import type { Quote } from '../types'; import AuthorList from '../primatives/author-list'; import Board from '../board/board'; import { getQuotes, generateQuoteMap, authors } from '../data'; import Title from '../primatives/title'; import AutoScrollOptionsSetter from './autoscroll-setter'; import { defaultAutoScrollerOptions } from… 证据：`stories/src/customize-autoscroll/customize-autoscroll-app.tsx`
- **With Controls**（source_file）：import React, { ReactElement } from 'react'; import type { ChangeEvent } from 'react'; import styled from '@emotion/styled'; import { DragDropContext } from '@hello-pangea/dnd'; import type { DropResult, DragUpdate } from '@hello-pangea/dnd'; import QuoteList from '../primatives/quote-list'; import { generateQuoteMap, authors } from '../data'; import { reorderQuoteMap } from '../reorder'; import { grid } from '../constants'; import type { Quote, QuoteMap, Author } from '../types'; ⋮---- class Controls extends React.Component< ⋮---- render ⋮---- interface State { quoteMap: QuoteMap; changeBy: number; isCombineEnabled: boolean; } ⋮---- componentDidMount : void componentWillUnmount : void ⋮---… 证据：`stories/src/dynamic/with-controls.tsx`
- **Types**（source_file）：import type { Id, Task } from '../types'; export interface Column { id: Id; title: string; taskIds: Id ; } export type ColumnMap = { columnId in Id : Column; }; export type TaskMap = { taskId in Id : Task; }; export interface Entities { columnOrder: Id ; columns: ColumnMap; tasks: TaskMap; } 证据：`stories/src/multi-drag/types.ts`
- **With Controls**（source_file）：import React, { useRef, useState, useCallback, ReactElement } from 'react'; import styled from '@emotion/styled'; import type { DropResult, PreDragActions, SnapDragActions, SensorAPI, } from '@hello-pangea/dnd'; import { DragDropContext } from '@hello-pangea/dnd'; import type { Quote } from '../types'; import QuoteList from '../primatives/quote-list'; import reorder from '../reorder'; import { grid, borderRadius } from '../constants'; interface ControlProps { quotes: Quote ; canLift: boolean; isDragging: boolean; lift: quoteId: string = SnapDragActions undefined null; } ⋮---- // locking the height so that the border width change // does not change the size of the button ⋮---- function Contr… 证据：`stories/src/programmatic/with-controls.tsx`
- **With Portal**（source_file）：import type { Property } from 'csstype'; import React, { Component, Fragment, ReactElement } from 'react'; import type { ReactNode } from 'react'; import ReactDOM from 'react-dom'; import styled from '@emotion/styled'; import { colors } from '@atlaskit/theme'; import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'; import type { DropResult, DroppableProvided, DraggableProvided, DraggableStateSnapshot, } from '@hello-pangea/dnd'; import { invariant } from '../../../src/invariant'; import reorder from '../reorder'; import { grid } from '../constants'; import type { Quote } from '../types'; ⋮---- interface TableCellProps { children: ReactNode; isDragOccurring: boolean; isDra… 证据：`stories/src/table/with-portal.tsx`
- **Types**（source_file）：import type { DraggableId, DraggableLocation } from '@hello-pangea/dnd'; export type Id = string; export interface AuthorColors { soft: string; hard: string; } export interface Author { id: Id; name: string; avatarUrl: string; url: string; colors: AuthorColors; } export interface Quote { id: Id; content: string; author: Author; } export interface Dragging { id: DraggableId; location: DraggableLocation; } export interface QuoteMap { key: string : Quote ; } export interface Task { id: Id; content: string; } 证据：`stories/src/types.ts`
- **Types**（source_file）：import { Quote } from '../types'; export interface NestedQuoteList { id: string; title: string; children: Array ; } 证据：`stories/src/vertical-nested/types.ts`
- 其余 4 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。

## 宿主 AI 必须遵守的规则

- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `package.json`, `CONTRIBUTING.md`
- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `package.json`, `CONTRIBUTING.md`

## 用户开工前应该回答的问题

- 你准备在哪个宿主 AI 或本地环境中使用它？
- 你只是想先体验工作流，还是准备真实安装？
- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？

## 验收标准

- 所有能力声明都能回指到 evidence_refs 中的文件路径。
- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。
- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。

---

## Doramagic Context Augmentation

下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。

## Human Manual 骨架

使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。

宿主 AI 硬性规则：
- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。
- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。
- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。

- **Core API: DragDropContext, Draggable, and Droppable**：importance `high`
  - source_paths: src/view/drag-drop-context/drag-drop-context.tsx, src/view/drag-drop-context/app.tsx, src/view/drag-drop-context/drag-drop-context-types.ts, src/view/draggable/draggable.tsx, src/view/draggable/draggable-types.ts
- **State Management and Internal Architecture**：importance `high`
  - source_paths: src/state/create-store.ts, src/state/reducer.ts, src/state/store-types.ts, src/state/action-creators.ts, src/state/middleware/lift.ts
- **Sensors and Input Handling**：importance `high`
  - source_paths: src/view/use-sensor-marshal/use-sensor-marshal.ts, src/view/use-sensor-marshal/sensors/use-mouse-sensor.ts, src/view/use-sensor-marshal/sensors/use-keyboard-sensor.ts, src/view/use-sensor-marshal/sensors/use-touch-sensor.ts, src/view/use-sensor-marshal/sensors/util/prevent-standard-key-events.ts
- **Advanced Features: Auto-Scrolling, Accessibility, and Patterns**：importance `high`
  - source_paths: src/state/auto-scroller/index.ts, src/state/auto-scroller/jump-scroller.ts, src/state/auto-scroller/fluid-scroller/config.ts, src/state/auto-scroller/fluid-scroller/scroll.ts, src/state/auto-scroller/fluid-scroller/auto-scroller-options-types.ts

## Repo Inspection Evidence / 源码检查证据

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `28c47a7a0139a09b1bf0a77a010e7121c39246d4`
- inspected_files: `pnpm-lock.yaml`, `README.md`, `package.json`, `docs/sensors/mouse.md`, `docs/sensors/touch.md`, `docs/sensors/keyboard.md`, `docs/sensors/sensor-api.md`, `docs/patterns/tables.md`, `docs/patterns/multi-drag.md`, `docs/patterns/virtual-lists.md`, `docs/about/examples.md`, `docs/about/design-principles.md`, `docs/about/accessibility.md`, `docs/about/browser-support.md`, `docs/about/animations.md`, `docs/about/installation.md`, `docs/support/engineering-health.md`, `docs/support/media.md`, `docs/support/community-and-addons.md`, `docs/support/upgrading.md`

宿主 AI 硬性规则：
- 没有 repo_clone_verified=true 时，不得声称已经读过源码。
- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。
- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。

## Doramagic Pitfall Constraints / 踩坑约束

这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。

### Constraint 1: 能力判断依赖假设

- Trigger: README/documentation is current enough for a first validation pass.
- Host AI rule: 将假设转成下游验证清单。
- Why it matters: 假设不成立时，用户拿不到承诺的能力。
- Evidence: capability.assumptions | github_repo:321362240 | https://github.com/hello-pangea/dnd | README/documentation is current enough for a first validation pass.
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 维护活跃度未知

- Trigger: 未记录 last_activity_observed。
- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Evidence: evidence.maintainer_signals | github_repo:321362240 | https://github.com/hello-pangea/dnd | last_activity_observed missing
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

- Trigger: no_demo
- Evidence: downstream_validation.risk_items | github_repo:321362240 | https://github.com/hello-pangea/dnd | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 4: 存在评分风险

- Trigger: no_demo
- Why it matters: 风险会影响是否适合普通用户安装。
- Evidence: risks.scoring_risks | github_repo:321362240 | https://github.com/hello-pangea/dnd | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 5: 来源证据：Dependency Dashboard

- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Dependency Dashboard
- Why it matters: 可能影响升级、迁移或版本选择。
- Evidence: community_evidence:github | https://github.com/hello-pangea/dnd/issues/210 | 来源讨论提到 node 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 6: issue/PR 响应质量未知

- Trigger: issue_or_pr_quality=unknown。
- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。
- Why it matters: 用户无法判断遇到问题后是否有人维护。
- Evidence: evidence.maintainer_signals | github_repo:321362240 | https://github.com/hello-pangea/dnd | issue_or_pr_quality=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 7: 发布节奏不明确

- Trigger: release_recency=unknown。
- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。
- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Evidence: evidence.maintainer_signals | github_repo:321362240 | https://github.com/hello-pangea/dnd | release_recency=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
