1实现原理 · 为什么它能做到
流程门禁:先冻结 Decision Contract(user job/decision scope/immutable facts/existing language/first-view invariant/interaction states/stop condition),再提议 3 个独立交互架构候选(命令优先/队列详情/对象主导/对比主导/ledger 优先等族),每个候选=一个交互假说而非皮肤,变量只动导航/选择/披露/动作归属/信息序。
Each candidate embodies a distinct interaction hypothesis rather than a skin.
build_board.py 是合规闸门:读 board.json(schemaVersion=interaction-design-board/v1),校验 2-8 个变体、变体文件不越 manifest 目录且非 symlink、sha256 去重(byte-identical 拒绝)、每个变体必须自包含 HTML(禁外部 script/img/link/poster/url() 资源、禁 CSS @import、必须有 title、禁 <base>),然后填模板产出单文件 Board。
f"{field} depends on external resource {locator!r}; inline it as CSS, JS, or data URL"
运行隔离=模板注入 CSP + srcdoc sandbox iframe:每个候选被包进 srcdoc frame,Board 向其注入 default-src 'none' 的 CSP(仅 unsafe-inline 样式/脚本 + data:/blob: 媒体,connect-src/frame-src/object-src/form-action 全禁),再叠 sandbox='allow-scripts allow-forms allow-modals'。
policy.content = "default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; img-src data: blob:; media-src data: blob:; font-src data:; connect-src 'none'; frame-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'"
测试时缩放(test-time scaling):有独立 worker 上下文时,一个候选派一个 worker、共享同一份冻结 contract、互不可见彼此输出,防收敛成兄弟方案;无 worker 则串行生成但重读冻结 contract 而非上一个候选。
assign one candidate to each worker with the same frozen decision contract and only that candidate's hypothesis. Do not let workers see one another's output.
反馈回路:Board 提交 feedback.json / feedback-pending.json(regenerated:true 时带 regenerateAction iterate|remix)→ agent 保留接受部分、改失败轴、只重生成受影响候选 → 版本化 Board 文件 → gstack serve 已存在则 POST /api/reload(响应 {"reloaded":true}),重复 serve 不算 reload。
curl -sS -X POST "${BOARD_URL%/}/api/reload" \ -H 'Content-Type: application/json' \ -d '{"html":"<absolute-versioned-board-path>"}'
生产实施门禁:用户确认反馈总结后才写 approved.json(选中/批准交互规则/first-view invariant/被拒 trade-off/实际演练状态/剩余未知/原型文件身份),然后才进产品实现并用真实浏览器验证同一代表任务——像素相似不算数。
Then—and only then—implement in the product.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | python3(build_board.py,纯 stdlib) |
| cli | gstack design 可执行(可选:serve Board + /api/feedback + /api/reload;未装则开文件直用) |
| cli | curl(可选:Board 重载探测/触发) |
4风险提醒 风险提醒:蓝色 · 知晓即可
- 候选原型 JS 在 allow-scripts 沙箱内可执行任意 UI 逻辑 — CSP 禁网/禁 frame,但脚本可操控 iframe 内 DOM、弹 modal(allow-modals);恶意候选可做 UI 内钓鱼/假状态——候选来源是 agent 自己生成的本地文件,属低风险但非零。
- feedback/approval 文件含用户原始表述 — session-dir 里的 feedback*.json/approved.json 记录用户原话与决策,若会话目录被同步/分享会外泄产品决策上下文。
- 实施阶段依赖 agent 守约 — 『只改受影响候选/不改产品数据模型/不写产品组件目录』等是文本纪律;build 校验管不到 agent 后续在真实产品树里的编辑。
5第二遍独立确认
- [ok] 穿越/symlink/外部资源拒绝 — resolve_variant: symlink 拒 + relative_to(root) 校验;validate_self_contained: RESOURCE_PATTERNS 扫 script/img/link/video/url(),仅放行 data:/blob:/about:。
- [ok] CSP 断网声明 — 模板 241 行 CSP 含 connect-src 'none'; frame-src 'none'; object-src 'none';srcdoc + sandbox allow-scripts allow-forms allow-modals 双保险。
- [ok] sha256 去重与变体数上限 — seen_hashes 重复即 ContractError;'2 <= len(variants) <= 8'。
- [ok] 无网络外发/凭证 — build_board.py imports 仅 stdlib(argparse/hashlib/html/json/re/sys/html.parser/pathlib);无 http/密钥。
- [unlocatable] gstack serve/reload 集成 — 依赖外部 gstack 工具(仓库外),本环境未安装;SKILL 中 serve/reload/反馈端点语义无法端到端验证,代码侧仅见模板对 __GSTACK_SERVER_URL 与 ./api/feedback 的 POST。
- [unlocatable] Board 内候选交互可用性(UI 层) — 模板 434 行含 tab/对比视图/反馈面板 JS,未在浏览器实测;fixtures+test_build_board.py 覆盖构建层而非视觉层。
6结论
bb7d5b878d07fe8e…d5c4678cb5