# impact-preview - Doramagic AI Context Pack

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

## 充分原则

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

## 给宿主 AI 的使用方式

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

## Claim 消费规则

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

## 它最适合谁

- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86

## 它能做什么

- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86

## 怎么开始

- `pip install impact-preview` 证据：`README.md` Claim：`clm_0003` supported 0.86, `clm_0009` supported 0.86
- `curl -X POST http://localhost:8000/api/v1/agents/register \` 证据：`README.md` Claim：`clm_0004` supported 0.86
- `curl -X POST http://localhost:8000/api/v1/actions \` 证据：`README.md` Claim：`clm_0005` supported 0.86, `clm_0007` supported 0.86
- `curl http://localhost:8000/api/v1/actions/ACTION_ID/preview -H "X-API-Key: YOUR_API_KEY"` 证据：`README.md` Claim：`clm_0006` supported 0.86
- `curl -X POST http://localhost:8000/api/v1/actions/ACTION_ID/approve -H "X-API-Key: YOUR_API_KEY"` 证据：`README.md` Claim：`clm_0007` supported 0.86
- `curl http://localhost:8000/api/v1/actions/ACTION_ID/events -H "X-API-Key: YOUR_API_KEY"` 证据：`README.md` Claim：`clm_0008` supported 0.86
- `pip install impact-preview[ui]` 证据：`README.md` Claim：`clm_0009` supported 0.86
- `git clone https://github.com/agent-polis/impact-preview.git` 证据：`README.md` Claim：`clm_0010` supported 0.86
- `pip install -e .[dev]` 证据：`README.md` Claim：`clm_0011` supported 0.86

## 继续前判断卡

- **当前建议**：需要管理员/安全审批
- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。

### 30 秒判断

- **现在怎么做**：需要管理员/安全审批
- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装
- **先别相信**：真实输出质量不能在安装前相信。
- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key

### 现在可以相信

- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86
- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86, `clm_0009` supported 0.86

### 现在还不能相信

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

### 继续会触碰什么

- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`
- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`
- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`
- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）
- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）
- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。
- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

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

## 哪些必须安装后验证

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

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0012` inferred 0.45
- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0013` supported 0.86
- **待确认**：真实安装后是否与用户当前宿主 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。

### 任务路由

- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86

### 上下文规模

- 文件总数：77
- 重要文件覆盖：40/77
- 证据索引条目：62
- 角色 / Skill 条目：7

### 证据不足时的处理

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

## Prompt Recipes

### 适配判断

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

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

### 安装前体验

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

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

请严格输出四段：
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
请基于 impact-preview 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```


## 角色 / Skill 索引

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

- **🔍 Agent Polis**（project_doc）：Impact Preview for AI Agents - "Terraform plan" for autonomous AI actions 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **Changelog**（project_doc）：All notable changes to this project will be documented in this file. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CHANGELOG.md`
- **CI Mode**（project_doc）：impact-preview-ci provides a deterministic, non-interactive evaluator for CI gate integrations. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CI_MODE.md`
- **CI Report Schema v1**（project_doc）：This document defines the machine-readable JSON report emitted by impact-preview-ci . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CI_REPORT_SCHEMA.md`
- **Code Mapping: v0.1 → v0.2 Pivot**（project_doc）：This document maps existing code to its role in the pivoted product. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CODE_MAPPING.md`
- **Agent Polis Pivot: Impact Preview for AI Agents**（project_doc）：Agent Polis Pivot: Impact Preview for AI Agents 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/PIVOT.md`
- **Roadmap**（project_doc）：Current Focus: Pivot to Impact Preview 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/ROADMAP.md`

## 证据索引

- 共索引 62 条证据。

- **🔍 Agent Polis**（documentation）：Impact Preview for AI Agents - "Terraform plan" for autonomous AI actions 证据：`README.md`
- **License**（source_file）：Copyright c 2026 Agent Polis Contributors 证据：`LICENSE`
- **Changelog**（documentation）：All notable changes to this project will be documented in this file. 证据：`docs/CHANGELOG.md`
- **CI Mode**（documentation）：impact-preview-ci provides a deterministic, non-interactive evaluator for CI gate integrations. 证据：`docs/CI_MODE.md`
- **CI Report Schema v1**（documentation）：This document defines the machine-readable JSON report emitted by impact-preview-ci . 证据：`docs/CI_REPORT_SCHEMA.md`
- **Code Mapping: v0.1 → v0.2 Pivot**（documentation）：This document maps existing code to its role in the pivoted product. 证据：`docs/CODE_MAPPING.md`
- **Agent Polis Pivot: Impact Preview for AI Agents**（documentation）：Agent Polis Pivot: Impact Preview for AI Agents 证据：`docs/PIVOT.md`
- **Roadmap**（documentation）：Current Focus: Pivot to Impact Preview 证据：`docs/ROADMAP.md`
- **Server**（structured_config）：{ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "io.github.agent-polis/impact-preview", "description": "Impact preview for AI agents - see what changes before any action executes.", "version": "0.2.2", "repository": { "url": "https://github.com/agent-polis/impact-preview", "source": "github" }, "packages": { "registryType": "pypi", "identifier": "impact-preview", "version": "0.2.2", "transport": { "type": "stdio" } } } 证据：`server.json`
- **20260130 002 Add Actions Table**（source_file）：revision: str = '002' down revision: str None = '001' branch labels: str Sequence str None = None depends on: str Sequence str None = None ⋮---- def upgrade - None ⋮---- def downgrade - None 证据：`migrations/versions/20260130_002_add_actions_table.py`
- **Init**（source_file）：version = "0.2.2" author = "Agent Polis Contributors" ⋮---- all = 证据：`src/agent_polis/__init__.py`
- **Init**（source_file）：all = "router", "TaskRequest", "TaskResponse", "TaskStatus" 证据：`src/agent_polis/a2a/__init__.py`
- **Models**（source_file）：class TaskStatus str, Enum ⋮---- SUBMITTED = "submitted" WORKING = "working" INPUT REQUIRED = "input-required" COMPLETED = "completed" CANCELED = "canceled" FAILED = "failed" ⋮---- class MessagePart BaseModel ⋮---- kind: str = Field description="Part type text, file, data " text: str None = Field default=None, description="Text content if kind=text" data: dict str, Any None = Field default=None, description="Data content if kind=data" mime type: str None = Field default=None, description="MIME type for files" ⋮---- class Message BaseModel ⋮---- role: str = Field description="Message role user, agent " parts: list MessagePart = Field default factory=list, description="Message parts" message… 证据：`src/agent_polis/a2a/models.py`
- **Simple routing logic will be expanded**（source_file）：logger = structlog.get logger router = APIRouter ⋮---- def json rpc error request id: str, code: int, message: str, data: Any = None - TaskResponse ⋮---- error = {"code": code, "message": message} ⋮---- def json rpc success request id: str, result: Any - TaskResponse ⋮---- params = request.params message data = params.get "message", {} task id = params.get "task id" ⋮---- message = Message ⋮---- task = await task store.get task id ⋮---- task = Task messages= message ⋮---- response message = await process task message task, message ⋮---- async def process task message task: Task, message: Message - Message ⋮---- text parts = p.text for p in message.parts if p.kind == "text" and p.text text =… 证据：`src/agent_polis/a2a/router.py`
- **Init**（source_file）：all = 证据：`src/agent_polis/actions/__init__.py`
- **Assess risks**（source_file）：logger = structlog.get logger ⋮---- prompt scanner = PromptInjectionScanner ⋮---- class ImpactAnalyzer ⋮---- HIGH RISK PATHS = ⋮---- SAFE PATH PREFIXES = ⋮---- CRITICAL PATTERNS = ⋮---- def init self, working directory: str None = None ⋮---- async def analyze self, request: ActionRequest - ActionPreview ⋮---- scan result = prompt scanner.scan action request request ⋮---- preview = await self. analyze file operation request ⋮---- preview = await self. analyze shell command request ⋮---- preview = await self. analyze db operation request ⋮---- preview = await self. analyze api call request ⋮---- preview = await self. analyze custom request ⋮---- scan risk = severity to risk level scan result.… 证据：`src/agent_polis/actions/analyzer.py`
- **Handle SQLite which doesn't preserve timezone info**（source_file）：class Action Base ⋮---- tablename = "actions" ⋮---- id: Mapped UUID = mapped column ⋮---- agent id: Mapped UUID = mapped column ⋮---- action type: Mapped str = mapped column ⋮---- description: Mapped str = mapped column ⋮---- target: Mapped str = mapped column ⋮---- payload: Mapped dict str, Any = mapped column ⋮---- context: Mapped str None = mapped column ⋮---- status: Mapped str = mapped column ⋮---- preview: Mapped dict str, Any None = mapped column ⋮---- risk level: Mapped str None = mapped column ⋮---- approved by: Mapped UUID None = mapped column ⋮---- approved at: Mapped datetime None = mapped column ⋮---- rejection reason: Mapped str None = mapped column ⋮---- modification comment:… 证据：`src/agent_polis/actions/db_models.py`
- **Stats**（source_file）：original lines = original.splitlines keepends=True modified lines = modified.splitlines keepends=True ⋮---- diff = difflib.unified diff ⋮---- diff = None lines added = 0 lines removed = 0 ⋮---- lines = new content.splitlines lines added = len lines diff = generate unified diff "", new content, path ⋮---- diff = generate unified diff original content, new content, path ⋮---- lines = original content.splitlines lines removed = len lines diff = generate unified diff original content, "", path ⋮---- diff = f"rename from {path}\nrename to {destination path}\n" ⋮---- def format diff terminal changes: list FileChange - str ⋮---- output = ⋮---- Stats ⋮---- def format diff plain changes: list FileCh… 证据：`src/agent_polis/actions/diff.py`
- **Models**（source_file）：class ActionType str, Enum ⋮---- FILE WRITE = "file write" FILE DELETE = "file delete" FILE MOVE = "file move" FILE CREATE = "file create" DB QUERY = "db query" DB EXECUTE = "db execute" API CALL = "api call" SHELL COMMAND = "shell command" CUSTOM = "custom" ⋮---- class ApprovalStatus str, Enum ⋮---- PENDING = "pending" APPROVED = "approved" REJECTED = "rejected" MODIFIED = "modified" EXECUTED = "executed" FAILED = "failed" TIMED OUT = "timed out" CANCELLED = "cancelled" ⋮---- class RiskLevel str, Enum ⋮---- LOW = "low" MEDIUM = "medium" HIGH = "high" CRITICAL = "critical" ⋮---- class FileChange BaseModel ⋮---- path: str = Field description="File path relative or absolute " operation: str =… 证据：`src/agent_polis/actions/models.py`
- **Router**（source_file）：logger = structlog.get logger router = APIRouter ⋮---- service = ActionService db ⋮---- response = service.to response action ⋮---- agent id = None if all agents else agent.id ⋮---- action = await service.get by id action id ⋮---- preview = ActionPreview action.preview ⋮---- comment = request.comment if request else None action = await service.approve action, agent, comment=comment ⋮---- action = await service.reject action, agent, request.reason ⋮---- action = await service.execute action, agent ⋮---- event store = EventStore db events = await event store.get stream f"action:{action id}" 证据：`src/agent_polis/actions/router.py`
- **Service**（source_file）：logger = structlog.get logger ⋮---- policy evaluator = PolicyEvaluator audit scanner = PromptInjectionScanner ⋮---- def builtin policy for request request: ActionRequest - PolicyConfig ⋮---- rules: list PolicyRule = ⋮---- class ActionService ⋮---- def init self, session: AsyncSession ⋮---- expires at = datetime.now UTC + timedelta seconds=request.timeout seconds ⋮---- action = Action ⋮---- preview = await self.analyzer.analyze request ⋮---- async def timeout expired self, action: Action - Action ⋮---- event = ActionTimedOut ⋮---- async def get by id self, action id: UUID - Action None ⋮---- result = await self.session.execute ⋮---- query = select Action .where Action.status == "pending" cou… 证据：`src/agent_polis/actions/service.py`
- **Init**（source_file）：all = "router", "AgentCreate", "AgentResponse", "AgentProfile", "AgentService" 证据：`src/agent_polis/agents/__init__.py`
- **Reset if new month**（source_file）：class Agent Base ⋮---- tablename = "agents" ⋮---- id: Mapped UUID = mapped column ⋮---- name: Mapped str = mapped column ⋮---- description: Mapped str = mapped column ⋮---- api key hash: Mapped str = mapped column ⋮---- reputation score: Mapped Decimal = mapped column ⋮---- verified: Mapped bool = mapped column ⋮---- verification method: Mapped str None = mapped column ⋮---- status: Mapped str = mapped column ⋮---- created at: Mapped datetime = mapped column ⋮---- last active at: Mapped datetime None = mapped column ⋮---- simulations this month: Mapped int = mapped column ⋮---- month reset at: Mapped datetime = mapped column ⋮---- simulations: Mapped list "Simulation" = relationship ⋮---- d… 证据：`src/agent_polis/agents/db_models.py`
- **Models**（source_file）：class AgentCreate BaseModel ⋮---- name: str = Field description: str = Field ⋮---- @field validator "name" @classmethod def validate name cls, v: str - str ⋮---- class AgentResponse BaseModel ⋮---- id: UUID name: str description: str api key: str = Field status: str created at: datetime ⋮---- class Config ⋮---- from attributes = True ⋮---- class AgentProfile BaseModel ⋮---- reputation score: float verified: bool verification method: str None ⋮---- last active at: datetime None simulation count: int = 0 ⋮---- class AgentUpdate BaseModel ⋮---- description: str None = Field ⋮---- class AgentStats BaseModel ⋮---- total simulations: int successful simulations: int failed simulations: int predict… 证据：`src/agent_polis/agents/models.py`
- **Router**（source_file）：logger = structlog.get logger router = APIRouter ⋮---- service = AgentService db ⋮---- new api key = generate api key ⋮---- agent = await service.get by name name 证据：`src/agent_polis/agents/router.py`
- **Service**（source_file）：logger = structlog.get logger ⋮---- class AgentService ⋮---- def init self, session: AsyncSession ⋮---- async def register self, data: AgentCreate - tuple Agent, str ⋮---- existing = await self.session.execute ⋮---- api key = generate api key api key hash = hash api key api key ⋮---- agent = Agent ⋮---- event = AgentRegistered ⋮---- async def get by id self, agent id: UUID - Agent None ⋮---- result = await self.session.execute ⋮---- async def get by name self, name: str - Agent None ⋮---- async def get profile self, agent: Agent - AgentProfile ⋮---- simulation count = result.scalar or 0 ⋮---- async def get stats self, agent: Agent, monthly limit: int - AgentStats ⋮---- total result = await… 证据：`src/agent_polis/agents/service.py`
- **Ci**（source_file）：REPORT SCHEMA VERSION = "1" ⋮---- class CIActionReport BaseModel ⋮---- index: int = Field ge=0 action type: str target: str risk level: str policy decision: str policy matched rule id: str None = None scanner max severity: str scanner reason ids: list str = Field default factory=list ⋮---- class CIReasonCount BaseModel ⋮---- reason: str count: int = Field ge=1 ⋮---- class CIPolicyReport BaseModel ⋮---- schema version: Literal "1" = REPORT SCHEMA VERSION policy version: str totals: dict str, int top blocking reasons: list CIReasonCount = Field default factory=list actions: list CIActionReport = Field default factory=list ⋮---- def decision exit code decisions: list PolicyDecision - int ⋮----… 证据：`src/agent_polis/ci.py`
- **Config**（source_file）：class Settings BaseSettings ⋮---- model config = SettingsConfigDict ⋮---- app name: str = Field default="agent-polis", description="Application name" app env: Literal "development", "staging", "production" = Field debug: bool = Field default=False, description="Debug mode" secret key: str = Field ⋮---- host: str = Field default="0.0.0.0", description="Server host" port: int = Field default=8000, description="Server port" ⋮---- database url: PostgresDsn = Field database echo: bool = Field default=False, description="Echo SQL queries" ⋮---- redis url: RedisDsn = Field ⋮---- e2b api key: str None = Field default=None, description="E2B API key for sandbox execution" ⋮---- rate limit requests: i… 证据：`src/agent_polis/config.py`
- **Init**（source_file）：all = 证据：`src/agent_polis/events/__init__.py`
- **Models**（source_file）：class Event Base ⋮---- tablename = "events" ⋮---- id: Mapped UUID = mapped column ⋮---- stream id: Mapped str = mapped column String 255 , nullable=False, index=True stream version: Mapped int = mapped column Integer, nullable=False ⋮---- event type: Mapped str = mapped column String 100 , nullable=False, index=True event data: Mapped dict str, Any = mapped column JSONType, nullable=False ⋮---- event metadata: Mapped dict str, Any = mapped column JSONType, nullable=False, default=dict ⋮---- created at: Mapped datetime = mapped column ⋮---- hash: Mapped str = mapped column String 64 , nullable=False prev hash: Mapped str None = mapped column String 64 , nullable=True ⋮---- table args = ⋮----… 证据：`src/agent_polis/events/models.py`
- **Init**（source_file）：all = 证据：`src/agent_polis/governance/__init__.py`
- **Descriptor Integrity**（source_file）：HASH PREFIX = "sha256:" HASH RE = re.compile r"^ 0-9a-f {64}$" ⋮---- def normalize hash pin pin: str - str ⋮---- """Normalize and validate a descriptor hash pin as sha256: .""" value = pin.strip .lower ⋮---- value = value len HASH PREFIX : ⋮---- def canonicalize descriptor descriptor: Mapping str, Any - str ⋮---- """Serialize descriptor to deterministic JSON used for hashing.""" ⋮---- def compute descriptor hash descriptor: Mapping str, Any - str ⋮---- canonical = canonicalize descriptor descriptor digest = hashlib.sha256 canonical.encode "utf-8" .hexdigest ⋮---- class DescriptorIntegrityPolicy BaseModel ⋮---- """Policy controlling descriptor integrity validation behavior.""" ⋮---- allowlis… 证据：`src/agent_polis/governance/descriptor_integrity.py`
- **Policy**（source_file）：class PolicyDecision str, Enum ⋮---- ALLOW = "allow" DENY = "deny" REQUIRE APPROVAL = "require approval" ⋮---- RISK ORDER = { ⋮---- def risk severity level: RiskLevel - int ⋮---- class PolicyDefaults BaseModel ⋮---- decision: PolicyDecision = Field default=PolicyDecision.REQUIRE APPROVAL ⋮---- class PolicyRule BaseModel ⋮---- id: str = Field min length=1 description: str None = None decision: PolicyDecision priority: int = Field default=100 enabled: bool = Field default=True ⋮---- action types: set ActionType = Field default factory=set path globs: list str = Field default factory=list target contains: list str = Field default factory=list min risk level: RiskLevel None = None max risk leve… 证据：`src/agent_polis/governance/policy.py`
- **Presets**（source_file）：class PolicyPresetMetadata BaseModel ⋮---- id: str = Field min length=1 name: str = Field min length=1 description: str = Field min length=1 tags: list str = Field default factory=list ⋮---- PRESET METADATA: dict str, PolicyPresetMetadata = { ⋮---- PRESET POLICIES: dict str, dict str, Any = { ⋮---- def list policy presets - list PolicyPresetMetadata ⋮---- def get policy preset metadata preset id: str - PolicyPresetMetadata ⋮---- available = ", ".join sorted PRESET METADATA.keys ⋮---- def load policy preset preset id: str - PolicyConfig ⋮---- """Load and validate a bundled policy preset by ID.""" ⋮---- available = ", ".join sorted PRESET POLICIES.keys 证据：`src/agent_polis/governance/presets.py`
- **Bounds to keep scanning predictable for untrusted inputs.**（source_file）：class ScanSeverity str, Enum ⋮---- LOW = "low" MEDIUM = "medium" HIGH = "high" CRITICAL = "critical" ⋮---- SEVERITY ORDER = { ⋮---- SEVERITY TO RISK = { ⋮---- def severity to risk level severity: ScanSeverity - RiskLevel ⋮---- class ScanFinding BaseModel ⋮---- reason id: str = Field min length=1 severity: ScanSeverity message: str = Field min length=1 field: str = Field min length=1 snippet: str = Field min length=1 ⋮---- class ScanResult BaseModel ⋮---- findings: list ScanFinding = Field default factory=list ⋮---- def max severity self - ScanSeverity ⋮---- def max risk level self - RiskLevel ⋮---- def to risk factors self - list str ⋮---- @dataclass frozen=True class ScannerRule ⋮---- reas… 证据：`src/agent_polis/governance/prompt_scanner.py`
- **Format result**（source_file）：CREWAI AVAILABLE = True ⋮---- CREWAI AVAILABLE = False CrewBaseTool = None ⋮---- BaseTool: type Any ⋮---- class FallbackBaseTool ⋮---- def init self, kwargs: Any - None ⋮---- = kwargs ⋮---- BaseTool = FallbackBaseTool ⋮---- BaseTool = CrewBaseTool ⋮---- JsonDict = dict str, Any ⋮---- class SimulationInput BaseModel ⋮---- name: str = Field description="Name of the simulation scenario" description: str = Field description="Description of what to simulate" code: str = Field description="Python code to execute in sandbox" inputs: dict str, Any = Field default factory=dict, description="Input variables for the code" timeout seconds: int = Field default=60, description="Execution timeout" ⋮---- c… 证据：`src/agent_polis/integrations/crewai.py`
- **Main**（source_file）：a2a router: APIRouter None simulations router: APIRouter None ⋮---- a2a router = None simulations router = None ⋮---- logger = structlog.get logger ⋮---- @asynccontextmanager async def lifespan app: FastAPI - AsyncGenerator None, None ⋮---- app = FastAPI ⋮---- @app.exception handler Exception async def global exception handler request: Request, exc: Exception - JSONResponse ⋮---- @app.get "/health", tags= "Health" async def health check - dict ⋮---- @app.get "/.well-known/agent.json", tags= "A2A" async def agent card - dict ⋮---- def cli - None 证据：`src/agent_polis/main.py`
- **Check critical patterns**（source_file）：mcp = FastMCP ⋮---- analyzer = ImpactAnalyzer working directory=os.getcwd ⋮---- def risk emoji risk: RiskLevel - str ⋮---- request = ActionRequest ⋮---- preview = await analyzer.analyze request ⋮---- output lines = ⋮---- query upper = query.strip .upper ⋮---- action type = ActionType.DB QUERY ⋮---- action type = ActionType.DB EXECUTE ⋮---- @mcp.tool def check path risk path: str - str ⋮---- path lower = path.lower ⋮---- risks = ⋮---- high risk patterns = ⋮---- Check critical patterns critical patterns = ⋮---- output = f"⚠️ Risk assessment for {path} :", "" ⋮---- @mcp.resource "config://working-directory" def get working directory - str ⋮---- @mcp.resource "config://risk-patterns" def get ri… 证据：`src/agent_polis/mcp_server.py`
- **Try to extract target from first positional arg**（source_file）：P = ParamSpec "P" R = TypeVar "R" ⋮---- JsonDict = dict str, Any JsonList = list JsonDict ⋮---- class ActionRejectedError Exception ⋮---- def init self, action id: str, reason: str ⋮---- class ActionTimedOutError Exception ⋮---- """Raised when an action times out waiting for approval.""" ⋮---- def init self, action id: str, timeout: int ⋮---- class AgentPolisClient ⋮---- """ Initialize the client. Args: api url: Base URL of the Agent Polis API api key: API key for authentication default timeout: Default timeout for approvals seconds poll interval: How often to poll for approval status """ ⋮---- action type = ActionType action type ⋮---- response = self. client.post ⋮---- def get action self… 证据：`src/agent_polis/sdk.py`
- **Init**（source_file）：all = 证据：`src/agent_polis/shared/__init__.py`
- **Init**（source_file）：all = 证据：`src/agent_polis/simulations/__init__.py`
- **Db Models**（source_file）：class Simulation Base ⋮---- tablename = "simulations" ⋮---- id: Mapped UUID = mapped column ⋮---- creator id: Mapped UUID = mapped column ⋮---- proposal id: Mapped UUID None = mapped column ⋮---- status: Mapped str = mapped column ⋮---- scenario definition: Mapped dict str, Any = mapped column ⋮---- e2b sandbox id: Mapped str None = mapped column ⋮---- result: Mapped dict str, Any None = mapped column ⋮---- predicted outcome: Mapped dict str, Any None = mapped column ⋮---- actual outcome: Mapped dict str, Any None = mapped column ⋮---- callback url: Mapped str None = mapped column ⋮---- created at: Mapped datetime = mapped column ⋮---- started at: Mapped datetime None = mapped column ⋮----… 证据：`src/agent_polis/simulations/db_models.py`
- **Models**（source_file）：class SimulationStatus str, Enum ⋮---- PENDING = "pending" RUNNING = "running" COMPLETED = "completed" FAILED = "failed" CANCELED = "canceled" ⋮---- class ScenarioDefinition BaseModel ⋮---- name: str = Field ⋮---- description: str None = Field ⋮---- code: str None = Field ⋮---- script url: str None = Field ⋮---- inputs: dict str, Any = Field ⋮---- environment: dict str, str = Field ⋮---- timeout seconds: int = Field ⋮---- expected outcomes: dict str, Any None = Field ⋮---- class SimulationCreate BaseModel ⋮---- scenario: ScenarioDefinition = Field ⋮---- proposal id: UUID None = Field ⋮---- callback url: str None = Field ⋮---- class SimulationRunRequest BaseModel ⋮---- timeout override: int… 证据：`src/agent_polis/simulations/models.py`
- **Router**（source_file）：logger = structlog.get logger router = APIRouter ⋮---- service = SimulationService db ⋮---- simulation = await service.create data, agent ⋮---- simulation = await service.get by id simulation id ⋮---- result = await service.run ⋮---- event store = EventStore db events = await event store.get stream f"simulation:{simulation id}" 证据：`src/agent_polis/simulations/router.py`
- **Update status**（source_file）：logger = structlog.get logger ⋮---- class SimulationService ⋮---- def init self, session: AsyncSession ⋮---- simulation = Simulation ⋮---- event = SimulationCreated ⋮---- Update status ⋮---- start event = SimulationStarted ⋮---- scenario = ScenarioDefinition simulation.scenario definition ⋮---- timeout = timeout override or scenario.timeout seconds inputs = { scenario.inputs} ⋮---- result = await self.executor.execute ⋮---- creator = await self.session.get Agent, simulation.creator id ⋮---- event: DomainEvent ⋮---- event = SimulationCompleted ⋮---- event = SimulationFailed ⋮---- meter event = SimulationMetered ⋮---- event = OutcomePredicted ⋮---- event = OutcomeActualized ⋮---- async def ge… 证据：`src/agent_polis/simulations/service.py`
- **Agent Polis Configuration**（source_file）：Agent Polis Configuration Copy this file to .env and fill in your values 证据：`.env.example`
- **Byte-compiled / optimized / DLL files**（source_file）：Byte-compiled / optimized / DLL files pycache / .py cod $py.class 证据：`.gitignore`
- **.Pre Commit Config**（source_file）：repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-json - id: check-added-large-files args: '--maxkb=1000' - id: check-merge-conflict - id: detect-private-key - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.9 hooks: - id: ruff args: --fix, --exit-non-zero-on-fix - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.8.0 hooks: - id: mypy additional dependencies: - pydantic - fastapi - sqlalchemy args: --ignore-missing-imports files: ^src/ - repo: local hooks: - id: check-secrets name: Check for secrets entry: bash -c 'grep -rn "api key\s =\s \"'\'… 证据：`.pre-commit-config.yaml`
- **Agent Polis Dockerfile**（source_file）：Agent Polis Dockerfile Multi-stage build for production 证据：`Dockerfile`
- **Alembic Configuration File**（source_file）：alembic path to migration scripts script location = migrations 证据：`alembic.ini`
- **Docker Compose.Prod**（source_file）：version: '3.8' services: app: build: context: . target: production restart: always ports: - "8000:8000" environment: - DATABASE URL=postgresql+asyncpg://postgres:${DB PASSWORD}@db:5432/agent polis - REDIS URL=redis://redis:6379/0 - APP ENV=production - DEBUG=false - SECRET KEY=${SECRET KEY} - E2B API KEY=${E2B API KEY} - LOG LEVEL=INFO - LOG FORMAT=json depends on: db: condition: service healthy redis: condition: service healthy networks: - agent-polis-network deploy: resources: limits: cpus: '2' memory: 2G reservations: cpus: '0.5' memory: 512M db: image: postgres:15-alpine restart: always environment: POSTGRES USER: postgres POSTGRES PASSWORD: ${DB PASSWORD} POSTGRES DB: agent polis volum… 证据：`docker-compose.prod.yml`
- **Docker Compose**（source_file）：version: '3.8' services: app: build: context: . target: production ports: - "8000:8000" environment: - DATABASE URL=postgresql+asyncpg://postgres:postgres@db:5432/agent polis - REDIS URL=redis://redis:6379/0 - APP ENV=development - DEBUG=true depends on: db: condition: service healthy redis: condition: service healthy volumes: - ./src:/app/src:ro networks: - agent-polis-network db: image: postgres:15-alpine environment: POSTGRES USER: postgres POSTGRES PASSWORD: postgres POSTGRES DB: agent polis ports: - "5432:5432" volumes: - postgres data:/var/lib/postgresql/data healthcheck: test: "CMD-SHELL", "pg isready -U postgres" interval: 5s timeout: 5s retries: 5 networks: - agent-polis-network re… 证据：`docker-compose.yml`
- **Run a quick simulation**（source_file）：API KEY = os.getenv "API KEY" API URL = os.getenv "API URL", "http://localhost:8000" ⋮---- def main ⋮---- CREWAI AVAILABLE = True ⋮---- CREWAI AVAILABLE = False ⋮---- me = client.get me ⋮---- Run a quick simulation ⋮---- result = client.simulate and run ⋮---- ===== Part 2: CrewAI Integration ===== ⋮---- polis tool = create crewai tool api url=API URL, api key=API KEY ⋮---- risk analyst = Agent ⋮---- validation task = Task ⋮---- crew = Crew ⋮---- result = crew.kickoff 证据：`examples/crewai_example.py`
- **Example 1: Submit a file write action**（source_file）：def main ⋮---- api url = os.getenv "API URL", "http://localhost:8000" api key = os.getenv "AGENT API KEY", "" ⋮---- client = AgentPolisClient api url=api url, api key=api key ⋮---- Example 1: Submit a file write action ⋮---- action = client.submit action ⋮---- Example 2: Get the preview ⋮---- preview = client.get preview action "id" ⋮---- Example 3: Get the diff ⋮---- diff result = client.get diff action "id" , format="plain" ⋮---- Example 4: Approve or reject ⋮---- approved = client.approve action "id" , comment="Approved via example script" ⋮---- Example 5: Execute ⋮---- executed = client.execute action "id" ⋮---- def decorator example ⋮---- Define a dangerous function with approval requi… 证据：`examples/impact_preview.py`
- **Check server health**（source_file）：API URL = os.getenv "API URL", "http://localhost:8000" ⋮---- def main ⋮---- Check server health ⋮---- response = httpx.get f"{API URL}/health", timeout=10 ⋮---- health = response.json ⋮---- Check A2A agent card ⋮---- response = httpx.get f"{API URL}/.well-known/agent.json", timeout=10 card = response.json ⋮---- Register an agent ⋮---- agent name = f"quickstart-{uuid.uuid4 .hex :8 }" ⋮---- response = httpx.post ⋮---- agent data = response.json api key = agent data "api key" ⋮---- Set up authenticated headers headers = {"X-API-Key": api key} ⋮---- simulation code = """ ⋮---- sim data = response.json sim id = sim data "id" ⋮---- Run the simulation ⋮---- result = response.json ⋮---- Get agent s… 证据：`examples/quickstart.py`
- **Env**（source_file）：config = context.config ⋮---- target metadata = Base.metadata ⋮---- def run migrations offline - None ⋮---- url = config.get main option "sqlalchemy.url" ⋮---- def do run migrations connection: Connection - None ⋮---- async def run async migrations - None ⋮---- connectable = async engine from config ⋮---- def run migrations online - None 证据：`migrations/env.py`
- **revision identifiers, used by Alembic.**（source_file）：Revision ID: ${up revision} Revises: ${down revision comma,n} Create Date: ${create date} 证据：`migrations/script.py.mako`
- **Pyproject**（source_file）：project name = "impact-preview" version = "0.2.2" description = "Impact preview for AI agents - see exactly what will change before any autonomous AI action executes" readme = "README.md" license = {text = "MIT"} requires-python = " =3.11" authors = {name = "Agent Polis Contributors"} keywords = "ai", "agents", "impact-preview", "approval-workflow", "autonomous-agents", "safety" classifiers = "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", 证据：`pyproject.toml`
- **Railway deployment configuration**（source_file）：Railway deployment configuration https://docs.railway.app/reference/config-as-code 证据：`railway.toml`
- **Render**（source_file）：services: - type: web name: agent-polis runtime: docker dockerfilePath: ./Dockerfile envVars: - key: DATABASE URL fromDatabase: name: agent-polis-db property: connectionString - key: REDIS URL fromService: type: redis name: agent-polis-redis property: connectionString - key: SECRET KEY generateValue: true - key: APP ENV value: production healthCheckPath: /health - type: redis name: agent-polis-redis plan: free maxmemoryPolicy: allkeys-lru databases: - name: agent-polis-db plan: free databaseName: agent polis 证据：`render.yaml`
- 其余 2 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。

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

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

- **Introduction to Agent Polis**：importance `high`
  - source_paths: README.md, src/agent_polis/__init__.py, src/agent_polis/main.py
- **Quick Start Guide**：importance `high`
  - source_paths: examples/quickstart.py, examples/impact_preview.py, docker-compose.yml
- **System Architecture**：importance `high`
  - source_paths: src/agent_polis/main.py, src/agent_polis/actions/__init__.py, src/agent_polis/governance/__init__.py, src/agent_polis/events/__init__.py
- **Data Flow and Models**：importance `high`
  - source_paths: src/agent_polis/actions/models.py, src/agent_polis/actions/service.py, src/agent_polis/actions/analyzer.py, migrations/versions/20260130_002_add_actions_table.py
- **Actions Module**：importance `high`
  - source_paths: src/agent_polis/actions/__init__.py, src/agent_polis/actions/analyzer.py, src/agent_polis/actions/router.py, src/agent_polis/actions/service.py, src/agent_polis/actions/diff.py
- **Governance and Policy**：importance `high`
  - source_paths: src/agent_polis/governance/policy.py, src/agent_polis/governance/presets.py, docs/CI_REPORT_SCHEMA.md
- **Security Scanners**：importance `medium`
  - source_paths: src/agent_polis/governance/prompt_scanner.py, src/agent_polis/governance/descriptor_integrity.py
- **CI Integration**：importance `high`
  - source_paths: src/agent_polis/ci.py, docs/CI_MODE.md, docs/CI_REPORT_SCHEMA.md, src/agent_polis/actions/router.py

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

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `600e309fa93fa7279d31d881df563e210a7a02c7`
- inspected_files: `pyproject.toml`, `Dockerfile`, `README.md`, `docker-compose.yml`, `docs/CODE_MAPPING.md`, `docs/CI_REPORT_SCHEMA.md`, `docs/CI_MODE.md`, `docs/PIVOT.md`, `docs/ROADMAP.md`, `docs/CHANGELOG.md`, `examples/quickstart.py`, `examples/impact_preview.py`, `examples/crewai_example.py`, `src/agent_polis/ci.py`, `src/agent_polis/mcp_server.py`, `src/agent_polis/sdk.py`, `src/agent_polis/main.py`, `src/agent_polis/__init__.py`, `src/agent_polis/config.py`, `src/agent_polis/a2a/router.py`

宿主 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: 来源证据：AP-101 Policy schema and parser

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：AP-101 Policy schema and parser
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能阻塞安装或首次运行。
- Evidence: community_evidence:github | cevd_52a7602d08fd4a34a02a058587179586 | https://github.com/agent-polis/impact-preview/issues/1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 来源证据：AP-102 Policy evaluator with deterministic precedence

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：AP-102 Policy evaluator with deterministic precedence
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能阻塞安装或首次运行。
- Evidence: community_evidence:github | cevd_7d4cca25cd1347289c9e6834c0f806fc | https://github.com/agent-polis/impact-preview/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 3: 来源证据：AP-203 Machine-readable CI policy report output

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：AP-203 Machine-readable CI policy report output
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能阻塞安装或首次运行。
- Evidence: community_evidence:github | cevd_71b0a0a48b3f4a3ea7107c911c8b8733 | https://github.com/agent-polis/impact-preview/issues/9 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

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

- Trigger: README/documentation is current enough for a first validation pass.
- Host AI rule: 将假设转成下游验证清单。
- Why it matters: 假设不成立时，用户拿不到承诺的能力。
- Evidence: capability.assumptions | mcp_registry:io.github.agent-polis/impact-preview:0.2.1 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.agent-polis%2Fimpact-preview/versions/0.2.1 | README/documentation is current enough for a first validation pass.
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

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

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

### Constraint 6: 下游验证发现风险项

- Trigger: no_demo
- Host AI rule: 进入安全/权限治理复核队列。
- Why it matters: 下游已经要求复核，不能在页面中弱化。
- Evidence: downstream_validation.risk_items | mcp_registry:io.github.agent-polis/impact-preview:0.2.1 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.agent-polis%2Fimpact-preview/versions/0.2.1 | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

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

- Trigger: no_demo
- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。
- Why it matters: 风险会影响是否适合普通用户安装。
- Evidence: risks.scoring_risks | mcp_registry:io.github.agent-polis/impact-preview:0.2.1 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.agent-polis%2Fimpact-preview/versions/0.2.1 | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 8: 来源证据：AP-105 Extend audit records with policy/scanner context

- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：AP-105 Extend audit records with policy/scanner context
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能阻塞安装或首次运行。
- Evidence: community_evidence:github | cevd_ff00c63559844328a271d0587352d351 | https://github.com/agent-polis/impact-preview/issues/5 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

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

- Trigger: issue_or_pr_quality=unknown。
- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。
- Why it matters: 用户无法判断遇到问题后是否有人维护。
- Evidence: evidence.maintainer_signals | mcp_registry:io.github.agent-polis/impact-preview:0.2.1 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.agent-polis%2Fimpact-preview/versions/0.2.1 | issue_or_pr_quality=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

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

- Trigger: release_recency=unknown。
- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。
- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Evidence: evidence.maintainer_signals | mcp_registry:io.github.agent-polis/impact-preview:0.2.1 | https://registry.modelcontextprotocol.io/v0.1/servers/io.github.agent-polis%2Fimpact-preview/versions/0.2.1 | release_recency=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
