quant-buddy-view · 量化看板发布
把「已验证的量化数据与公式」沉淀成一个公开可分享、实时取数的网页看板/落地页。本技能不做一次性行情查询或回测探索;默认执行路线是:
feishu-group 渠道:打包渠道为
feishu-group时,direct/fork/unmatched/update 等所有分支禁止发送非终态链接;终态 contract 统一把pages.quantbuddy.cn/pages/<owner>/<page_id>.html转成www.quantbuddy.cn/playground/<owner>/<page_id>,内部发布与验收仍使用原始托管 URL。
最高优先级:既有活页解读。 用户给出 pages.quantbuddy.cn/pages/... 的 QuantBuddy 活页 URL,且意图是“解读 / 分析当前活页 / 看这页数据”时,先且只运行:
python scripts/static_page.py interpret '{"url":"用户提供的页面 URL"}'
这是只读数据路径,不要运行 trace_context.py、templates、template、direct_deliver、new_page、fork、download、浏览器或 HTML 搜索,也不要创建、更新、发布页面。它调用 getPageDetail?need_data=true;服务端使用页面绑定的公式包和 Data Grant 取最新数据,并附加 interpretation_bundle,不返回 signature。直接按用户的自定义要求解读详情与 interpretation_bundle.runtime_data。未指定格式时,依次输出一句话结论、关键指标及变化、风险/异常、3 个继续追问方向。详见 workflows/interpret-existing-page.md。
若 interpretation_bundle.runtime_data.grants[].data.mode="csv",先返回的 csv_fields[].csv_url 是短期下载链接而非可直接计算的数据。必须紧接着运行一次 python scripts/static_page.py interpret_csv '{}':它只下载该次 interpret 已返回的 CSV、保留链接并补出 results[].fields[].series,然后再计算和解读;禁止重跑 interpret、另查数据接口或把 CSV 链接给用户。
- 除上述既有活页解读分支外,在任何后端请求前运行
scripts/trace_context.py begin,保存唯一task_id并在后续命令中复用。这步本身就是后端写入调用,必须和后续命令带同一个身份(QBV_API_KEY环境变量或参数里的api_key),不带会被记成 skill 默认账号。 - 若用户只是要简单分析一只 A 股并返回页面,且没有定制栏目/版式、额外指标/公式/图表、对比或多标的要求,直接运行一次
scripts/static_page.py new_asset_page。成功结果包含完整数据草稿agent_reply_markdown_draft;当前 Agent只需依据用户原问题和草稿前五章数据补写综合观察,不再查 templates,也不另跑 QBS 验证或注册 Grant。 - 除上述快速场景外,运行一次
scripts/static_page.py templates,查询统一 public 命中池(服务端一次返回官方精选+社区)。 - direct 只有在范式、范围和全部请求维度三轴均有证据时成立;
direct_deliver必须提交dimension_check。缺维度改走 fork +same_paradigm_augment_dimension。 - fork/unmatched 调用
new_page时由 Agent 根据items_summary显式传routing_decision;fork 还必须声明borrow_mode=inherit|inherit_augment|compose。fork 一旦判定只能继承、增强继承或 Compose,禁止改判 unmatched。 new_asset_page成功后,按agent_summary_request用当前 Agent补写草稿中的唯一summary_marker,保持其余内容不变并立即发送;direct、fork/unmatched 仍按agent_reply_contract和回复模板生成证据绑定草稿,再运行返回的reply_validation_command,只有valid=true才最终回复。
多轮追问:首次用户消息运行
scripts/trace_context.py begin;同一task_id的每条后续用户消息先运行scripts/trace_context.py beginTurn。正常 Agent 必须同时传本轮可选agent_intent:简洁展开上下文指代并写清对象、动作、约束和期望页面/产物,推荐 20~160 字;不得复制用户原话、输出内部推理或提前编造结论。老调用方可省略并按null继续。一轮内所有 QBV/QBS 工具共享同一turn_id。Turn 是审计旁路:服务端记录失败会返回tracking_recorded:false,但不得阻断建页、更新、取数或发布;业务上下文继续切换到真实user_query/agent_intent,attemptedturn_id不保存、不传播,后续按无 Turn 模式继续。更新既有活页必须继续复用原page_id与公开 URL。
QBS 并行 Handoff:收到
qbs_qbv_handoff_v1时运行scripts/trace_context.py beginHandoff(兼容begin-handoff),传入 Handoff object 或绝对handoff_file。必须原样复用其中真实task_id + turn_id + source_skill_id,不得再次begin/beginTurn、不得在 QBV 重做 QBS 路由分类。create/existing_page之后仍进入本 Skill 完整 SOP,由 QBV 判断 direct/fork/unmatched、查询 ownership 并执行本人原位更新或他人复制;高风险持久状态未确认时beginHandoff必须拒绝。
何时用本技能 vs quant-buddy-skill
- 探索/一次性查询("茅台今天涨跌幅"、"跑个均线金叉回测看看")→ 用 quant-buddy-skill。
- 要一个能反复看、能发给别人、数据会自动更新的页面 → 切到 quant-buddy-view;已有文件转活页先静态托管,其他从零研究建页再按探索流程。
已有文件转活页:静态托管优先(高于查数与范式路由)
用户提供已有 JPG/PNG、HTML、PDF 或其他可读取文件,并要求转活页、网页活化、用 QBV 做成可分享页面时,按语义触发,不依赖“转活页”固定词。即使同时要求检查错误、补充指标、研究或重做 HTML,也必须先把来源转换为可阅读的静态 HTML、发布并验收、先交付链接,再考虑 QBS 数据接入。不得先查数据、匹配资产、查询范式或等待 Handoff/计算胶囊;这些工作均移到静态交付之后。仅阅读/分析/导出文件、未要求发布,或明确“先不要发布”时不触发。
执行 已有文件静态优先工作流。首次托管使用 upload(已明确可写目标则 update)和 transformation_mode:"preserve_html_qbs_live", snapshot_only:true;来源是转换后的静态 HTML,不是 JPG/PDF 二进制。先确认公开页面可访问并回传稳定 page_id / URL,说明“静态来源预览,尚未实时化/核验”;再同页增强。快照阶段返回 transformation_status:pending,不是转换失败,也不是任务已完成。数据未命中不得阻止静态交付;只有文件不可读、转换/快照/首次托管失败或公开授权边界不明等真实阻碍才能停在首次交付前。
新会话路由:单股快速返回 / 其余查范式卡
先建立 Trace Context。begin 是真实的后端写入调用(落审计表),和后续命令一样需要本次任务的身份——必须与后续命令用同一个 key,否则这一步会被记到 skill 默认账号名下,任务链路从第一条记录起就归错人:
# 身份走环境变量(exec 日志里会脱敏);不要把 key 拼进命令串,命令是原样记录的
QBV_API_KEY=<本次任务的 key> python scripts/trace_context.py begin '{"user_query":"那和五粮液比呢?","agent_intent":"延续上一轮贵州茅台分析,对比五粮液的盈利能力、估值水平与主要风险。","agent_model":"当前真实运行模型(明确知道时才传)"}'
agent_intent 与本轮 user_query 绑定:首问、每次追问分别保存,追问要展开“它/上一个/继续”等指代;缺失、空白或旧 Trace 文件均按 null,不能从 user_query 伪造。QBS Handoff 继续使用 qbs_qbv_handoff_v1,可选携带同一 Intent;Intent 差异不得制造第二个 Turn、拒绝 Handoff 或改变 Job 身份。
agent_model 是纯可选审计字段:明确知道当前 Agent 的真实运行模型时建议传入;不确定时直接省略,禁止猜测,也不要询问用户。宿主也可通过可选环境变量 QBV_AGENT_MODEL 注入。模型名按“显式参数 → QBV_AGENT_MODEL → 当前 task_id 的任务临时上下文 → 空”解析;缺失、纯空白或上下文读写失败都不得中断任务,非空值会通过 x-agent-model 自动贯穿后续命令与 QBS bridge。
保存返回的 task_id,并把它加入本次任务后续每个 static_page.py、formula_package.py、data_grant.py 参数。脚本会通过 x-task-id 请求头透传,使后台能从提问一直聚合到最终活页链接。new_asset_page / templates / upload / update / publish_final / publish_verified 缺少 Trace Context 时必须停止执行。QBV 编排中的 quant-buddy-skill 工具统一通过 scripts/qbs_bridge.py <tool> @params.json 调用,并显式传同一 task_id + user_query;bridge 会用 task-scoped session 继承 task_id,禁止生成第二个 session id。
build_dashboard.py也属于上述“后续每个命令”:只要 spec 含upload:true或update_page_id,必须写入同一task_id。成功结果会返回 hash-boundreply_draft_file + reply_validation_command;公网验收后必须写草稿并运行该命令,只有valid:true才能最终回复,之后停止工具调用。
具体资产证据闸门:已有文件转活页先执行静态交付,本闸门仅在其后实时增强阶段生效。除 new_asset_page 固定场景外,只要用户点名具体资产,就在 Trace 后、解释资产身份或提交 routing_decision 前,按「Trace → 资产映射 → 最小接口验证 → 页面路由」的顺序完成验证:调用 scripts/qbs_bridge.py resolve_asset_data 得到平台 ticker 映射,并按页面实际需要探测所需数据角色是否可取数,只记录接口成功/失败、可用字段和结构化错误。页面结构与 direct/fork/unmatched 判断只依据"用户所需能力 × 已验证的平台能力",不得依据 Agent 对公司上市状态、所有权、资产名称或市场惯例的记忆。验证前不得引入"上市/未上市、公开/私营、代理资产、无行情、只能静态"等限制性前提;若用户没有询问这些身份属性,也不要把它们扩展成分析主线。
resolve_asset_data 的输入合同必须直接按下面形状写入新的 output/*.json,不要先猜 schema、不要把多只资产拼成一个 asset 字符串,也不要为每只资产各写一份参数文件:
{
"task_id": "<同一 task_id>",
"user_query": "<当前用户原问题>",
"assets": ["贵州茅台", "五粮液", "泸州老窖"],
"required_roles": {
"snapshot": ["close", "pct_chg", "pe_ttm", "pb", "market_cap"]
},
"optional_fields": ["turnover_rate"]
}
- 单资产用
"asset":"贵州茅台";多资产用"assets":[...],二者不能并存。多资产由 bridge 在一次 CLI 调用内逐资产验证并聚合收据。 required_roles只需写实际需要的 role;省略的profile/snapshot/report/formula自动视为空数组。每个 role 的规范值是字符串数组,也兼容{"fields":[...]}。- 多资产探测阶段的
formula必须留空或省略;跨资产公共公式只在探测后用validate_package_set验证一次,禁止每个资产重复验证/注册同一公式包。 output/是跨会话残留的 scratch,不是示例库:禁止 Grep/Read 旧output/*.json来拼本次参数,尤其禁止复制其中旧task_id、旧凭证、旧公式或损坏 JSON;参数形状只从当前SKILL.md/tools/*.md/workflows/*.md获取。- 含双引号的公式必须写成合法 JSON 转义;优先使用无嵌套引号的等价公式(如
mt_close = 收盘价(贵州茅台))。写入后直接执行对应 CLI,让 JSON parser 作为反馈,不要读取旧 scratch 文件“找范例”。 - 多资产累计收益/回撤优先走标准看板:同一组价格
outputs分别配置transform:"cumulative_return_pct"与transform:"drawdown_pct",估值另用 Data Grant table。此能力已由build_dashboard内置,禁止为它 Grep/Readassets/data-kernel.js或手写 bespoke SSE/Grant runtime;详见workflows/dashboard-end-to-end.md的最短路径。
已有 URL 修改按写权限原位更新或 Fork
只有用户明确要求“解读/查看当前页面”且不要求修改时,才使用不带 task_id 的纯只读 interpret,读取后即可按返回证据回答,不进入建页流程。
用户要求修改已有 QuantBuddy URL 时,先 trace_context.py begin,再带同一 task_id 调用 static_page.py interpret。必须按返回的 existing_page_route.mode 分流,不能把所有已有页一律判成 Fork:
mode="in_place":调用者是 owner/page admin,或旧版详情合同返回resource_role="existing_page"、由updateStaticPage在写入时做最终权限校验。保持原page_id、公开 URL、包/Grant、Share Shell 与运行时身份,使用static_page.py update(以及需要时的update_progress/publish_verified)写回原页。禁止new_page、new_asset_page、upload创建替代链接,也不需要再次查询templates。若chart_edit.py返回LEGACY_PAGE / NO_RENDER_JS_MARKER,而用户已明确要求修改本人页面并保持原链接,则必要的技术性结构升级已获授权:立即按workflows/edit-existing-chart.md的 legacy fallback 下载、最小重建、浏览器预检并update同一页,不得二次询问是否升级,也不得停在本地 HTML。只有缺失信息会改变业务语义时才询问。若服务端返回FORBIDDEN,停止写入并转入下述 Fork 路径,不得伪造is_page_admin。mode="fork":当前详情明确can_update_in_place=false,或该页是不可直接写入的source_template。依次执行templates(recommend="all") → new_page(mode=fork, source_template_id=<interpret 返回>) → fork_prepare;templates 只补齐范式池凭据,不能覆盖 interpret 已绑定的来源。
可信权限字段由服务端 getPageDetail 返回:can_update_in_place 与 access_role=owner|page_admin|reader。客户端不得相信调用参数里自报的 is_page_admin;旧服务端尚未返回 capability 时,只允许尝试写回 interpret 绑定的同一个 page_id,并以 updateStaticPage 的 owner/page-admin 鉴权结果为准。
Fork 路径在决策绑定前禁止 new_asset_page、build_dashboard、bespoke upload 或任何 regenerated page;不得改判 unmatched 或偷换来源。只有 fork_prepare 明确返回结构化不可复制错误后,才允许评估降级,并显式声明 page_context_mode=regenerated 与 source_page_context_inherited=false。
从 QBS 并行交接进入(薄适配,不改变 QBV 独立 SOP)
当父任务提供 qbs_qbv_handoff_v1 文件时,不再执行 begin,而是:
python scripts/trace_context.py beginHandoff '{"handoff_file":"D:/.../handoff.json"}'
python scripts/qbs_handoff_adapter.py evaluate '{"handoff_file":"D:/.../handoff.json","qbv_job_id":"qbvjob_xxx","qbv_job_file":"D:/.../job.json"}'
trace_context.py 原样复用 QBS 的 task_id + turn_id;Adapter 校验可选 qbs_computation_capsule_v1,并在发现对应 qbs_qbv_job_v2 时确定性把 Job 从 queued 写为 running。QBV standalone 没有该 Job 时为无副作用 no-op:
coverage=covered:禁止再次调用resolve_asset_data或其它 QBS 工具重算covered_roles;直接消费胶囊里的资产映射、合同、artifact、字段映射、结论和收据,然后继续 QBV 页面 SOP。coverage=partial:只允许通过qbs_bridge.py补missing_roles,不得重复已覆盖 role。coverage=unusable:无损回退本节原有 Trace →qbs_bridge→ 路由流程,不得降低验证门禁。- Adapter 返回
formula_runtime_action=register_exact时:把formula_runtime_contract.formulas按原顺序、原字面注册为 Formula Package,并按合同中的reads首次查询;禁止缩写指标名、合并公式、重新推导或再次调用 QBS 验证 covered 公式。fingerprint、左值或 reads 校验失败时按coverage=unusable安全回退,不得注册被篡改合同。旧 Handoff 没有formula_runtime_contract时保持原 standalone/兼容流程。
这里跳过的只是本轮重复计算。direct/fork/unmatched、本人原位更新/他人复制、Grant/Package 注册、运行时首次查询、页面构建、Card Runtime、发布和公网验收仍由 QBV 完整执行。QBS Job 只做旁路审计:publish_verified 同时取得 published=true + verified=true + page_id + public_url,或 direct_deliver 取得字段一致的强终态 direct_finalize contract 后,会自动写回 completed;无法继续且确定终止时执行 python scripts/qbs_handoff_adapter.py fail-job '{"qbv_job_id":"qbvjob_xxx","qbv_job_file":"D:/.../job.json","failure_code":"<CODE>","retryable":true}',不得手改 Job JSON。用户直接使用 QBV 时没有 Handoff,继续走原 SOP,不依赖 QBS 胶囊。source_skill_id=null + source_skill_id_status=unavailable 是合法审计状态,不得阻断页面流程,也不得猜测历史 skill_*。
单一 A 股简单分析快速通道
用户只要求分析一只 A 股并给出可分享页面,且没有定制栏目/版式、指定额外指标/公式/图表、对比、多标的、指数或港美股要求时,直接执行:
python scripts/static_page.py new_asset_page '{"task_id":"task_xxx","asset":"贵州茅台","user_query":"分析贵州茅台"}'
该命令调用服务端固定场景,并在内部读取 SHA256 绑定 evidence、生成前五个数据章节、上报终态和清理临时文件。数据章节按有数据才生成表格、整篇最多五表;计算维度以 stock profile 的稳定画像维度为主证据、有效收盘价 CSV 的日涨跌/均线/价格位置为补充,两路均无可核验字段时才整节省略,且后续可见章节自动连续编号。消息面章节暂不输出。成功结果包含 agent_reply_markdown_draft + agent_summary_request:草稿第一至第五章就是交给当前 Agent的完整可见证据,第六章只有唯一 summary_marker。Agent必须结合本轮真实用户问题,用自己的语言直接回答用户目的,只引用草稿已有数据,提炼结论和关键依据;走势类问题使用条件式判断,财报点评聚焦报告表现,其他问题同样按原意组织,不需要关键词分类器或专用生成器。完成后只替换 marker,不改前五章、免责声明和最终链接块,不运行 validator 或其它工具,立即发送完整 Markdown。公开链接和“若效果不满意,页面可进一步升级”仍是最后两行。CSV 单项失败只删除对应字段并写 warning;完全没有可核验证据或草稿生成失败时 fail closed,不得退化成一句链接或重复调用。后续若用户要改这张自有页面,继续使用 update 保持同一个 page_id / URL。
不满足上述窄条件时,只运行一次 scripts/static_page.py templates。它调用统一 public 列表,由服务端完成官方精选+社区的去重、排序和分页;不要再手工重复调用。返回值是 item_count + 覆盖全部候选的 items_summary(不再是原始 items 全量打印),完整候选落盘在 full_result_file;正常路由判断只需要读 items_summary,不需要也不应该去读 full_result_file。
- ① 直接命中(范式匹配、范围一致,且候选真实 runtime 输出覆盖用户请求的每个维度):
templates一旦给出精确命中,普通渠道的下一条用户可见消息必须立即发送现成download_url/public_url,中间不允许任何工具调用。推荐文案:已直接命中现成活页:[标题](URL)。我继续核对实时数据并补充分析。;若agent_reply_hint.delivery_policy.emit_intermediate_url=false(即feishu-group),禁止发送该 URL,直接继续。- 普通渠道发出链接后、
feishu-group不发链接而是立即运行一次:python scripts/static_page.py direct_deliver '{"task_id":"task_xxx","page_id":"page_xxx","template_revision":"sha256","dimension_check":{"coverage":[{"dimension":"用户维度","covered_by":["card_required_outputs:真实输出"]}]}}'。标题和简介只能作辅助证据;每个维度至少需要card_required_outputs,或由 runtime 合同派生的page_context.primary_outputs权威证据。 - 不
new_page、不注册、不 fork、不研究脚本源码、不先跑--help。direct_deliver的公式结果固定为 summary;grant 完整结果只写%TEMP%,最终回复不得暴露本地路径或凭证。 - 只有返回
agent_reply_contract.terminal=true且operation=direct_finalize才允许最终收口;失败时说明具体错误,不得用已发送的链接绕过终态门禁。回复模板和page_context沿用原页。 direct_deliver会返回真实 contract、草稿、校验参数的%TEMP%\qbv_<完整 task_id>_*文件路径及reply_validation_command。只把 Markdown 写入返回的reply_draft_file,执行返回的命令一次;valid=true后立即最终回复,禁止再次校验、运行--help、扫描临时目录或继续搜索 memory。成功校验会统一清理 contract、draft、params 和 grant 临时结果。- 公网浏览器验收成功后的下一步必须是最终回复;不得再调用 Read/Grep/Bash/浏览器或进入新的研究轮次。若浏览器验收是最后一个可用工具轮次,也必须用已验证 contract/URL 直接收口。
- 用户之后说"要改这个页面内容" → 转 ② fork(官方/社区链接不能直接改,只能新建自己的链接后改)。
- 边界:范式匹配但标的/股票池/指数/市场范围不一致(如命中的是茅台估值页、用户问的是宁德时代;命中沪深300异动页、用户问中证500)不算直接命中,落到 ②。只有资产无关且市场范围一致的全市场范式,才可不依赖具体标的直接命中。
- ② fork(范式命中但标的不符,或用户要改内容):
先运行
new_page,传routing_decision:{"mode":"fork","source_template_id":"page_xxx","reason_code":"same_paradigm_different_asset","borrow_mode":"inherit"}。inherit_augment用于模板结构可沿用但缺分析维度;compose用于合同无法逐项继承、但布局/样式/渲染函数/公式思路或 Grant 形状仍可借鉴。fork_prepare是一次性 task 绑定:重复执行返回FORK_ALREADY_BOUND;确需整体重建必须传force_rebuild:true + rebuild_reason,同 task 禁止换来源模板。fork_prepare 返回 publish_command 后即进入发布收敛阶段:只填写返回的 review 文件并执行该命令,禁止读取scripts/*.py、运行--help或探索publish_workflow.py/fork_runtime_contract.py实现;命令失败只按结构化错误修正输入。已创建首链时必须完成 terminal 或明确失败收口,不得让进度页长期停留在 running。inherit_augment向fork_prepare传augmentation_spec,新增 package/grant 角色与来源角色物理隔离。新增公式必须通过 QBS 验证,marker 必须恰好出现一次且输出必须被实际渲染。compose先运行intent_profile做 user_term/platform_dimensions/method_terms 三层映射,再用research_templates提取 credential-free 的栏目 HTML、CSS、渲染函数及合同形状,最后fork_compose提交借鉴清单。收据及 SHA256 绑定后才允许发布;全部 original 的零借鉴 Compose 被拒绝。fork_compose必须传borrow_plan.modules(不是顶层borrowed_refs),并逐项认领 intent profile 的每个user_term;优先复制research_templates.templates_summary[].fork_compose_example后修改,遇到COMPOSE_BORROW_PLAN_REQUIRED必须按返回示例重试,不得停在 running 进度页。Compose 参数必须一次写完整:
intent_profile至少传{"task_id":"task_xxx","asset_scope":{"kind":"sector","name":"目标资产组","market":"A股"},"dimensions":[{"user_term":"实时行情","platform_dimensions":["close","pct_chg"],"method_terms":["横向比较"]}]};research_templates传{"task_id":"task_xxx","template_ids":["page_source"]}。任一结构化错误若返回example_intent_profile、example_research_templates或fork_compose_example,必须直接复制该完整示例后修改并重试,不能逐字段猜测。 - 资产替换的职责分工:Agent 说清楚"换成哪只标的",脚本负责"这只标的在页面里写成什么样"。来源主资产由脚本从模板公式词频 + 标题推导,代码的实际写法(SH600900/600900.SH/ 裸600900)由脚本扫描来源 HTML 得出,只替换真实存在的写法——不要去猜来源 HTML 里代码写成什么样,你看不到那个文件。多资产/指数类范式推不出主资产时返回FORK_SOURCE_ASSET_AMBIGUOUS(报错自带候选名与可照抄的调用),用source_asset显式指明后重试。asset_replacements仅作可选覆盖。替换后主资产若仍有残留,在写出工作 HTML 前就返回FORK_SOURCE_ASSET_RESIDUAL,不会等到发布后才发现。Agent只在
fork_prepare生成的review_update_params_file.decisions中填写required_decisions声明的业务决策:规则性同业矩阵填target_slots,复杂跨资产公式填target_formulas,标签替换填page_label_replacements。decisions已按角色预生成嵌套占位骨架({"roles":{"<role_id>":{...}}}),只需要在骨架里补全空值,不要新增/改写顶层字段,也不要把required_decisions里的扁平decision_id(如roles.package.package_001.target_formulas)当成提交用的 key。禁止直接编辑标准 fork HTML/review。Grant按来源角色完整继承
kind/query_type/fields/dimensions/window_days/result_mode与 CSV/inline 合同,只允许自动修改 manifest 声明的资产范围字段;其他变化必须填写contract_change_reason。继承 Grant 的数据级失败可降级并继续发布存活角色;鉴权/配额/协议等系统级失败仍阻断。若页面仍用
queryDataGrant无条件消费失败 Grant,返回GRANT_DEGRADATION_UNSAFE,不得用空凭证假降级。先运行
fork_prepare返回的review_update_command;只有review_state.status=complete且生成 review receipt 后,才运行publish_command。发布器从同一 canonical package/Grant 合同派生 QBS 验证与注册,自动检查 required outputs、公式左值、reads、PE/PB 水位公式具有明确算法与正整数窗口、Grant fingerprint、Marker 唯一性与 Card Runtime 结构,并让一次注册结果扇出到页面/Card全部位置。fork_manifest_v2禁止手工传 packages、grants、Marker 或完整 workflow JSON,出现MANUAL_RUNTIME_BINDINGS_FORBIDDEN时回到生成的 publish plan,不要写临时替换脚本。v1 prepared task 继续按旧接口发布。这不是建议——
publish_verified服务端会按 fork manifest 里的凭证数量强制核验:手工分步调用publish_verified(task_id, page_id, html_file, source_template_id, fork_manifest_file, validation_receipt_files)只有在这个页面零凭证(纯静态改造)时才会放行,否则直接拒绝并返回error:"PUBLISH_WORKFLOW_REQUIRED";出现该错误时改走publish_workflow.py,不要绕过。回复 = 回复模板格式 + 自己的新链接(数值同样用自己的包/grant query 填)。
- ③ 未命中(无匹配范式):Agent 根据
items_summary调new_page时传routing_decision:{"mode":"unmatched","closest_template_id":"page_xxx","reason_code":"required_capability_missing","reason":"候选缺少用户要求的核心能力"};存在候选却只因标的/范围不同而判 unmatched 会被提示改走 fork。记录成功后继续build_dashboard/ bespoke 自建 → 其余同 ②;feishu-group同样不发送进度链接。
后续追问:自己的链接 →
update同page_id;命中的官方/社区链接要改 → 只能转 ② fork 成自己的链接后再改。
默认路由
- 简单单一 A 股综合分析(无定制、额外指标/图表、对比或多标的要求):
trace_context begin后直接new_asset_page返回自有实时页面。 - 其他固定页面形态(定制个股页、成分股异动榜、多因子选股看板、商品日报等):先
templates查询官方精选+社区命中池;direct 直接用列表 URL + revision,fork 才读取和改写模板详情。 - 宽宝活卡 / 精华卡 / 封面卡(范式卡 artifact):把页面精华做成独立 card runtime artifact(
embedded-card-v1:页面内嵌<template data-qb-card-template>+data-qb-card-manifest+QBCardRuntimeV1runtime),供官网卡片流在空白宿主中独立 hydrate。静态首帧card_snapshot_url由skill_server按 artifact hash 生成,是页面封面的唯一来源(整页缩略图能力已下线)。按 guides/essence-cover-card.md 生成;已发布页优先用preserve_visual:true只升级协议。完整重建必须显式传visual_contract,否则CARD_VISUAL_REQUIRED停止;用verify_page.mjs --card-runtime-only --require-card-visual-contract验收新 artifact。卡片必须官网浅色系、固定信息骨架、可变核心可视化;不再用旧的?cover=1URL 模式。 - 没有合适在线模板:再走
workflows/dashboard-end-to-end.md,用build_dashboard生成声明式实时看板。 - 声明式看板也不够:才走
guides/bespoke-page.md写 bespoke 主体 HTML,并用公共 shell 编译成自包含页面。 - 改一个已有图表(叠加/去掉一条线、改时间窗口、查真实数据):优先
workflows/edit-existing-chart.md+scripts/chart_edit.py,只动被要求的那一处、不重新验证/计算页面上其它无关系列;只有目标页面是 legacy (chart_edit.py inspect判定,多为本次改动之前生成的老页面)或改动本质上要求整页重算/换版式,才落回 下面的整页重建。 - 改造已发布/已生成页面:优先
scripts/retrofit_share_shell.py,再static_page.py update保持同一个page_id/ URL;正式 update 应传具体change_note,版式变化显式传change_aspect:"layout",其它类型可让服务端推断。 - Share Shell revision 4 页面问答边界:可见页头由官网
/embed/live-page-headeriframe 托管,活页 Parent Bridge 只执行刷新、收藏、分享、认证导航和移动 WebAgent 动作、页面问题携题自动发送并校验qb-live-page-header-v1/qb-web-agent-v1;官网 WebAgent Preview 注入qb-live-page-embed-context=webagent-preview时不得加载页头或预加载收藏 iframe。官网只改页头视觉不要求逐页刷新;Parent Bridge、通信协议或能力契约变化才提升 revision。 - 用户可见链接策略:普通渠道 direct 在
templates命中后、下一次工具调用前发现成 URL,fork/unmatched 在new_page返回后立即发首链;feishu-group看到delivery_policy.emit_intermediate_url=false后禁止发送任何非终态 URL,只在 validator 通过后发送 terminal contract 的 playgroundpublic_url。进度页仍用update_progress和publish_final更新同一page_id;未显式传change_note时,版本修改描述按“状态 + 中文阶段标题 + 用户可见 message”自动生成,正式发布版本默认记录“完成发布:正式活页内容已发布”。 - Agent 回复模板:活页 metadata 可带
agent_reply_template指向本技能reply-templates/下的回复骨架。reply-templates/是 Agent 最终回复格式,不是活页 HTML 页面模板;不要和在线templates/templateAPI 混用。 - 本 skill 不再内置本地页面样板,不能从本地历史样板目录或低质 HTML 骨架起步。
Agent 回复模板(agent_reply_template)
活页用同级 page_context 描述用途/模块/输出,用 agent_reply_template.template_ref 指向 reply-templates/ 的 Markdown 骨架。字段契约、hybrid 规则和发布继承见 tools/static_page.md。
page_context不得包含实时数值、api_key、signature、Bearer token 或本地路径;fork 后必须按最终页面重建,direct 才沿用原页。- 读取型命令返回
agent_reply_hint.terminal=false;new_page/update_progress也不是终态。成功的new_asset_page/direct_deliver/direct_finalize/upload/update/publish_final/publish_verified可返回agent_reply_contract.terminal=true;其中new_asset_page返回含唯一综合观察 marker 的agent_reply_markdown_draft和面向当前 Agent的agent_summary_request。 - fork/unmatched 遇到必须由用户决定的口径时,用同一
task_id/page_id进入waiting_input,用户回答后继续原任务;不要重新建 Trace 或首链。feishu-group的 waiting hint 不含public_url,提问时也不得附带进度链接。 - fork 必须使用
fork_prepare绑定来源和 manifest,最终publish_final保持首链 URL、移除来源凭证并保留必需栏目/输出/Card Runtime;详细门禁见 workflows/new-session-paradigm-routing.md。 - prepared fork task 禁止
build_dashboard;v2只填写生成的 review-update 决策文件,依次运行review_update_command和publish_command。只有旧 v1任务继续使用手工fork_validate路径。 - 带
task_id的进度从package_register起必须传同任务的结构化验证证据:实时页提交route_receipt、grant_receipts、formula_receipts,且selected_routes必须逐项对应实际注册凭证;自由文本validation_not_required_reason不再放行。纯静态内容只能用static_content_only;资产实时探测全部数据级失败时只能凭live_data_route_receipt_v1使用static_after_live_probe。 new_asset_page的最终回复只允许把agent_reply_markdown_draft的唯一summary_marker替换为 Agent撰写的综合观察;不得改写、删减或重排其它内容,也不得把 marker 发给用户。综合观察首句直接回答本轮用户目的,后续只选最相关证据解释,避免复述全部五章;没有足够证据时明确说明边界,不得补造事实。该分支不返回 evidence 路径或校验命令。其他终态回复必须按回复模板输出并且只能使用 contract 的public_url;feishu-group下该字段必须是https://www.quantbuddy.cn/playground/<owner>/<page_id>。**只要终态回复包含public_url,必须把可分享实时活页:[{public_url}]({public_url})作为最后倒数第二行,最后一行固定为“若效果不满意,页面可进一步升级”;链接不得在正文、章节或免责声明中提前出现。**一般模板依据reply_render_policy与reply_data_availability删除结构性不存在的字段、整列、整行和空可选章节。single_stock_deep_dive_v1还必须读取 SHA256 绑定的reply_data_evidence_file,保留全部七节标题,有数据的模板字段全部输出,整节无数据使用标准说明;只有有效结构中的偶发缺值才写--。若delivery_policy.max_markdown_tables存在,整篇不得超过该表格数,超出的结构改用列表或行内文本且不得丢数据。validator 返回valid=true后原样发送validated_markdown,不得再次压缩或改写,也不得暴露原始托管 URL、本地路径、凭证或内部日志。- 除
new_asset_page外,最终回复前只运行一次发布器返回的reply_validation_command。reply_validation_env是进程内执行专用值,CLI 与持久化报告只允许返回[REDACTED]和reply_validation_env_keys,禁止输出真实凭证。若发布时显式设置了QBV_API_KEY,validator 命令必须继承同一个现有环境变量;未显式覆盖时由config.json/config.local.json解析默认账号,发布器返回中不携带默认配置 key。禁止把 key 拼进命令串或另写参数文件。validator 必须读取发布器生成的contract_file + contract_sha256,不得手工重建精简 contract。direct 使用direct_deliver返回的完整 task ID 路径和命令,成功后自动清理。valid=true后不再执行任何工具调用。 - 没有 terminal contract 禁止完成任务。唯一例外是成功的
waiting_inputcheckpoint。 - 性能门槛:普通渠道模板命中到首链不超过 5 秒;所有渠道 terminal 到最终回复不超过 45 秒,完整活页任务以 10 分钟内完成为常态目标,用户可见消息间隔不超过 60 秒。回复证据补读不设额外人工截止时间,但必须按模板字段过滤、相同模式批量读取且每批最多10个;禁止公式重算和 package/grant 重查。
- 逐指标声明最新可得日期和实际覆盖范围。未做浏览器验收时,只能声明公开 URL 和实时接口可访问。
前置依赖:公式必须先验证
本技能运行时自包含:注册/生成/发布只凭本技能 config.json 的 api_key。但注册公式包前,每组公式必须先在 quant-buddy-skill 里用 runMultiFormulaBatchStream 跑通确认出数;服务端试读只是兜底,不替代这一步。
如果当前环境没有 quant-buddy-skill,Agent 不要跳过验证或直接注册公式包。
普通已安装 skill 用户先检查全局 skills;缺失时运行安装命令,已安装但需要刷新时运行更新命令,二选一,不要连续执行:
npx skills list -g --json
# 未安装时
npx skills add pseudo-longinus/quant-buddy-skills -g --all
# 已安装、需要刷新时
npx skills update pseudo-longinus/quant-buddy-skills -y
- Windows 上若 symlink /
EPERM报错,在add命令末尾追加--copy重试。 - 在源码 checkout 或 junction 调试本 skill 时,不要运行上面的 bundle 级
add --all/update覆盖当前quant-buddy-view。QBV 解析活动 QBS 的固定优先级是QBS_SKILL_ROOT、同级quant-buddy-skill/、同级quant-buddy-skill__skillhub/;以scripts/call.py存在为准。不得用 glob/递归扫描,也不得把quant-buddy-skill-backup-*当成可运行 skill。 - 安装后必须确认 quant-buddy-skill 的
config.json.api_key或QUANT_BUDDY_API_KEY可用;只报告“已配置/未配置/鉴权成功或失败”,不要打印 key 或完整 config。若鉴权失败,停下来说明 blocker,不要继续注册公式包。 - 若只是上传/改造一份真正不含资产、市场数据和来源凭证的纯静态 HTML,可继续使用本技能并声明
static_content_only。资产实时页面必须通过qbs_bridge.py resolve_asset_data完成统一探测;只有required_roles.formula非空时才运行公式验证,普通行情、估值和财务不得为了触发公式包而改写成公式。
推荐让两个 skill 同级安装,便于验证公式和迁移旧公式包凭证:
<skills 目录>/
quant-buddy-skill/ 或 quant-buddy-skill__skillhub/ ← 探索 / 公式验证(runMultiFormulaBatchStream、confirmDataMulti)
quant-buddy-view/ 或 quant-buddy-view__skillhub/ ← 本技能:注册 Formula Package / Data Grant、生成看板、发布
旧凭证迁移见 tools/formula_package.md。
入口选择(先判断类型)
固定页面先查在线范式卡;direct 用 direct_deliver,fork 才下载和改写来源 HTML。不要从本地历史样板或低质骨架起步。
| 类型 | 展示名 | 入口 | 什么时候用 |
|---|---|---|---|
| 单股快页 | A 股个股综合分析 | scripts/static_page.py new_asset_page |
简单分析一只 A 股并返回页面;无定制/对比/额外指标要求 |
| 页面模板 | 官方精选 + 社区 | scripts/static_page.py templates |
其他固定页面形态;direct 直接交付,范围不一致才 fork |
| 回复模板 | Agent 回复骨架 | reply-templates/ | 活页 metadata 的 agent_reply_template.template_ref;用于约束 Agent 最终 Markdown 回复格式,不生成 HTML |
| 封面组件 | 宽宝活卡 / 精华卡 | guides/essence-cover-card.md | 独立 4:3 embedded-card-v1 artifact;按指南实现和验收 |
| 通用流程 | 标准实时看板 | workflows/dashboard-end-to-end.md | 用户要“做成可分享看板/链接”,但没有指定固定页面模板 |
| 增量维护 | 单图表增删改查 | workflows/edit-existing-chart.md | 自己的已发布页面要加/删一条线、改时间窗口、查真实数据——只改一个图表,不是整页重建 |
| 开发指南 | 自定义页面 | guides/bespoke-page.md | build_dashboard 做不出的自定义 HTML/CSS/SVG 页面,或迁移已有 HTML |
| 迁移工具 | 旧页套公共外壳 | tools/retrofit_share_shell.md | 已发布/已生成 HTML 需要去掉旧二维码、旧页头、旧页尾,并保留同一个 page_id 更新 |
| 设计系统 | 活页 UI/UX 系统 | guides/live-page-ui-ux-system.md | 新建或整体重构活页时,选择页面原型、主题 token、字体/密度、可组合模式和响应式转换;统一体验底线但保留页面身份 |
| 维护指南 | 浏览器批注与整页 UI refinement | guides/browser-feedback-refinement.md | 用户针对已有自有页面的字体层级、间距、章节导航、sticky/折叠、响应式或分享交互提出修改;保持同一 page_id、runtime 合同和页面视觉身份 |
- 简单单一 A 股综合分析优先走
new_asset_page;定制单标的画像/估值财务、指数成分异动、多因子工作台仍先匹配对应在线范式,范围不一致才 fork。详细页面契约由服务端固定场景或模板/构建脚本门禁,不在此重复。 - fork 后禁止沿用来源
package_id/grant_id/signature;必须验证并注册当前用户凭证。 - 所有页面复用
assets/share-shell/;分享壳、海报、Card Runtime 和迁移细则分别读取对应guides/,不要手写重复组件。 - 公式注册与读取模式见 tools/formula_package.md,数据授权见 tools/data_grant.md,静态页命令和 metadata 见 tools/static_page.md。
- 普通自有页面用
update保持 URL;published template 用template判定,除非用户明确维护原模板,否则只读复用或 fork。
取数:实时页的两条通道
实时页可使用 Formula Package 或 Data Grant:公式包在 HTML 内嵌 package_id + signature,打开时调用 queryFormulaPackage;数据授权内嵌 grant_id + signature,打开时调用 queryDataGrant。两类凭证可以同页混用,彼此独立取数;底层数据更新后无需重建页面,访问者打开或刷新即可取得最新数据。spec 不需要写 mode 字段。
- 页面是"活"的:数据不焊进 HTML,运行时实时取;构建期只取一次数做质量体检(数据健康 + 单标的文案一致性),不内联。
- 关联字段平级:页面 metadata 中
package_ids与grant_ids分别记录两类凭证;任一通道都可以单独支撑实时页,也可以同时存在。 - 通道按数据性质选择:普通行情、估值和财务优先 Data Grant;确需计算、自定义公式口径时才使用 Formula Package,不得为了让页面成为实时页而强行改写成公式。
- 共同前提(均已满足):
queryFormulaPackage/queryDataGrant对页面域名pages.quantbuddy.cn放开 CORS,且两类signature都是允许嵌入页面的公开取数能力令牌。 - ⚠️ 协议必须一致:页面发布在
https://,config.json的endpoint也必须是https://,否则浏览器会以 mixed-content 拦截取数。当前 endpoint 已是https://www.quantbuddy.cn/skill。
数据授权(Data Grant)vs 公式包 —— 页面免 key 取数的第二条通道
脚本 scripts/data_grant.py 已可用,
build_dashboard与assets/data-kernel.js已支持 grant 面板,与公式包同页混用。契约见 tools/data_grant.md、服务端设计见skill_server/docs/dataGrant相关文档/数据授权-技术设计文档.md。选凭证类型时按下面取舍表对照。
数据授权与公式包共用同一套签名免 key 心智:页面 HTML 内嵌一个凭证(公式包是 package_id + signature,数据授权是 grant_id + signature),访问者打开页面时免 key 实时取数。区别在钉死的是什么——公式包钉死"一组公式 + 读取模式"(会重算,走 SSE);数据授权钉死"一次平台直取数请求"(无重算,普通 JSON)。
取舍规则(选凭证类型时对照):
| 页面要展示的数据 | 用哪条通道 | 凭证 |
|---|---|---|
| 算出来的指标 / 回测净值 / IC / rankIC / 时序 / 自定义公式口径 | 公式包 | package_id |
| 平台白名单直取的行情 / 估值 / 财务 / 资金流(收盘价、涨跌幅、PE/PB…) | 数据授权 fast_query |
grant_id |
| 个股预计算画像卡(估值/财务质量等维度画像) | 数据授权 stock_profile |
grant_id |
| 已上线维度分的 TopN / 榜单 / 异动名单(动量反转、趋势结构…) | 数据授权 composition_select |
grant_id |
- 一句话:要"算"的用公式包;平台"直取/直选"的有界数据用数据授权。原公式包 RANK 角色仍保留给"算指标"型多因子选股,不被 composition_select grant 取代。
- 资产实时页面统一入口:先调用
scripts/qbs_bridge.py resolve_asset_data @params.json,显式声明required_roles.profile/snapshot/report/formula与optional_fields。路由按stockProfile → fast_query(snapshot) → fast_query(report) → 必需公式执行;普通行情、估值和报告期财务优先fast_query,不得为了触发公式包而改写普通字段。 - 禁止先验假设:
resolve_asset_data探测前不得依据 Agent 对公司上市状态、所有权、资产名称或市场惯例的记忆推断平台是否可取数,也不得据此提前选择代理资产、静态说明、数据通道或页面结构;未验证前只能说"我先验证平台资产映射和数据可用性"。 - 按业务覆盖判成功:顶层
success:true不代表页面数据完整。目标资产必须存在,required fields 必须有有效值,且不得出现在asset_errors/field_errors;optional field 失败只记 warning。部分核心角色成功返回incomplete,不得冒充完整页面。 - 静态回退是硬门禁:
ASSET_NOT_FOUND、DATA_UNAVAILABLE、空结果、目标资产/required field 缺失等数据级失败可以继续下一独立通道;鉴权、配额、task/session、网络、超时、协议和服务错误必须返回blocked。只有live_data_route_receipt_v1证明所有核心实时角色都已探测且均为数据级失败,才允许static_after_live_probe;static_content_only仅限没有资产、市场数据和来源凭证的纯静态内容。 - 发布只认证据:Grant-only、formula-only 与混合页面均可发布,但必须提交 route/grant/formula 结构化收据,并让 route receipt 的
selected_routes与实际 Grant/公式收据逐项对应;禁止自由文本 waiver。 - 两套并存:探索/验证仍在 quant-buddy-skill 用 api-key 跑三接口(fastQuery / stockProfile / selectByComposition);本技能只负责把验证过的请求注册成 grant 嵌页。api-key 那套一行不改。
- 硬门槛同公式包:注册任何 grant 前,先在 quant-buddy-skill 用 api-key 跑通对应接口、确认命中/出数,再回本技能注册。
- 固定场景例外:
new_asset_page的三份 Grant payload 由skill_server固定生成并做结构/白名单校验,Agent 不接触也不自行注册,因此该快速通道不额外执行 quant-buddy-skill 预验证;页面打开时按 Grant 实时取数。 - 同源约束:
access_dunhe=false(页面绝不返回付费/敦和数据)、CORS/https 协议一致、signature 是公开凭证不打印给用户——与公式包完全一致。
硬规则
- 中文参数走 @file 或环境变量:Windows PowerShell 命令行直接传中文会被 GBK 截断。注册公式、写 spec 一律用
@params.json(UTF-8)或FP_PARAMS/BD_PARAMS/SP_PARAMS环境变量。 - 公式必须先验证再注册(硬门槛):fork v2 由
publish_workflow.py根据 review 解析出的最终 package 边界自动调用validate_package_set,验证与注册从同一个{formulas,reads,begin_date}合同派生。Agent负责检查 review 中的公式语义、目标资产和同业映射,不得绕过生成的 plan 单独注册;复杂跨资产公式未审核、required outputs/reads 不一致,或 PE/PB 水位输出没有明确算法与正整数窗口时,发布器在网络调用前拒绝。fork 默认继承来源模板已经声明且能通过 QBS 的水位口径,不强制改成固定250日。 - 验证参数也要换干净:调用
runMultiFormulaBatchStream时,user_query必须反映当前用户请求和当前资产;若传task_id必须为本次新任务。复制示例时不能只替换formulas,却留下“贵州茅台 factsheet”等旧user_query,否则后台审计和回放会被污染。 - signature 是凭证:不要打印到面向最终用户的对话里;看板会把它写进公开 HTML 供实时取数,发布前确认可接受。
- 标签来源不要写 Agent:显式传
scene_tags/paradigm_tags时,tagging_method用manual/migration/unknown;需要 LLM 自动识别就调用scripts/static_page.py autotag。不要再传tagging_method:"agent",也不要在tagging_meta.method里写agent。 - 失败要说清:脚本返回
code != 0时,向用户复述「卡在哪一步(命令名)+ 错误摘要」,不要以空白或纯日志结束。 - 具体资产必须先验证,再解释或路由:当用户请求涉及具体资产,尤其是美股、港股、ETF、特殊名称或中英文混写资产时,必须先执行上方"具体资产证据闸门"(
resolve_asset_data探测);不要等到准备作负面判断时才验证。不得根据现实上市状态、所有权、公司常识、历史记忆或资产名称直觉,推断平台是否可取数,也不得据此选择代理资产、静态说明、数据通道或页面结构。资产库命中只证明 ticker 映射,resolve_asset_data探测成功才证明对应数据能力;按用户实际需要验证行情/估值、画像、财务或其他数据,禁止为"更全面"无边界扩查。验证结果必须区分资产未映射、接口不支持、字段缺失和额度限制;单个字段缺失、窗口受限或额度限制不得扩大表述为资产不可用。只有工具证据与用户需求直接相关时,才在页面或回复中说明上市/私营、代理或市场身份;未验证前只能说「我先验证平台资产映射和数据可用性」。 - 正文图片先上传后引用:先用
static_page.py image_upload获得目标page_id下的绝对https://pages.quantbuddy.cn/pages/assets/...webpURL,再写入 HTML;禁止跨页复用托管 URL。图片必须带明确alt与width/height;首屏和海报目标内不得 lazy,正文下方才可loading="lazy"。标准 image panel 默认启用当前页大图预览,装饰图才设zoomable:false;不要用新窗口打开图片 URL。fork 必须按 manifest 的images[]上传到目标页并替换 marker,不能保留来源图片 URL。 templates摘要必须覆盖全部候选,落盘失败不能裸奔:items_summary的条目数量必须等于item_count(完整候选去重后的真实数量,不是服务端可能未重算的total),不允许只看其中一部分候选就判定unmatched;一旦返回error:"TEMPLATES_PERSIST_FAILED"或error:"TEMPLATES_RESPONSE_SHAPE_UNEXPECTED"(落盘失败或响应结构异常),必须先向用户说明「范式候选未能完整确认,暂缓路由判断」,禁止在这种不完整信息下判定为unmatched走自建,也不得通过重复调用templates来补救(每个任务仍然只能调用一次这条硬规则不变);确需重试仅限明确的瞬时网络失败,且只重试一次。- Card Runtime 先做零副作用结构预检:含 Card Runtime artifact 的 HTML 必须由
publish_workflow.py在 QBS 验证、注册、图片上传和发布前用假凭证执行verify_page.mjs --card-runtime-structure-only。正文与 Card 共用凭证时用 marker 数组扇出;每个数组元素仍须全局唯一并在 HTML 中恰好出现一次。禁止空 manifest 凭证;普通<img>必须有非空src,仅显式声明data-qb-runtime-src且等待运行时赋值的预览图可以暂时为空;同时禁止注册等价的重复 Card package/grant。 - 普通建页前必须先查范式卡并显式确认路由:
new_page会校验完整候选并绑定路由。fork 必须声明借鉴度,且一经判定不得改判 unmatched;继承不成立时只能在 fork 内降为 Compose。build_dashboard对 fork/inherit* 禁止整页构建;fork/compose 仅在fork_compose绑定后允许emit:"panel_block"。 - 本地验收与公网验收分责:
fork-local在本地file://(origin=null)下用放开同源策略的测试浏览器跑真实取数渲染(security_mode:"disabled-web-security"),布局/占位符/运行时错误/图片/Card Runtime 门禁照常执行;public-smoke保持浏览器默认安全策略,数据接口 CORS/Failed to fetch/运行时失败仍严格拦截。平台注入的/webapi/skill/track分析埋点是 fire-and-forget,其 CORS/网络失败降为non_core_console_warnings,不再让成功页面发布失败;数据接口(queryDataGrant/queryFormulaPackage)的失败仍是阻塞性核心错误。 - Fork 数据通道必须继承来源合同:fork 的目标是替换标的并保持来源范式运行合同,不是重新设计数据层。来源模板某一角色使用公式包,目标页同一角色继续使用公式包;来源使用
fast_query/stock_profile/composition_select数据授权,目标页继续使用同 kind、同 query_type、同响应形状的数据授权。禁止仅因“财务数据通常可走 fast_query(report)”就在 fork 中把来源财务公式包改成 grant,也禁止反向把来源 grant 改成公式包。只有unmatched/ 明确从零重建时才重新做通道选择;此时平台白名单报告期财务优先fast_query(query_type="report")。 - 已有文件先静态托管,再保真接入 QBS:所有已有文件转活页先执行 静态优先工作流,不以文件格式、是否含非 QBS 接口或查数成功为前提。以下约束仅描述 HTML 保真增强阶段,不缩窄入口范围。当用户说“把这个本地 HTML/页面活页化、标准化处理”,且来源页调用用户自己的非 QBS 服务接口时,不走在线模板 fork,也不要求
qbs_qbv_handoff_v1。执行顺序固定为“先快照保底、再同页渐进增强”:先创建或复用稳定page_id,把来源页当前可见状态原样写入该链接;若来源含fetch/axios/XMLHttpRequest/EventSource/WebSocket等异步逻辑,必须先运行scripts/capture_rendered_html.mjs(或等价浏览器捕获)得到渲染完成且已冻结旧脚本的快照,并传source_snapshot_html_file + source_snapshot_html_sha256。随后再验证/注册 QBS:直取数据使用 Data Grant,需要计算的口径使用公式包;成功区域才声明data-qb-live-mode="live",并按通道增加data-qb-live-tag="qbs-formula-package|qbs-data-grant"。未转换区域保持快照原 DOM,不要求、也不得为了声明静态而注入data-qb-live-mode="static"。完整或部分成功后都在同一个page_id写回:成功区域显示右上角低干扰● LIVE,失败区域继续显示首次快照;全部失败或第二次写回失败时,活页仍保留完整快照,不生成通用错误页、不创建替代链接。来源/快照缺失、不可读或 SHA256 不一致时,在首次托管写入前 fail closed。终态自动使用preserve_html_qbs_live_delivery_v1,按transformation_status如实说明 complete/partial/failed,并单独回传page_id和公开链接。本阶段只增加成功区域的 div live 声明与标准可见徽标,不引入data-qb-block-id、Block Runtime 或 Block 持久化。 - CHANGELOG 仅作为版本审计:维护、升级或排查历史行为变化时,先阅读
CHANGELOG.md中最新版本及与问题相关的历史条目;执行页面任务时,当前规则仍以SKILL.md+workflows/**+tools/**+guides/**为准。CHANGELOG 可能包含已被后续版本反转或废弃的旧口径,禁止用历史条目覆盖当前规则。
工具一览
参数约定:所有脚本参数是一个 JSON 字符串位置参数(或
@params.json/ 环境变量),如list '{"scope":"test_all"}'。命令行也兼容--scope test_all/--key=value直觉写法(仅简单参数;公式、spec 等复杂结构仍走@file/环境变量以免 GBK 截断)。
| 脚本 | 命令 | 作用 | 文档 |
|---|---|---|---|
scripts/formula_package.py |
register / query / list / revoke / refresh |
公式任务包:注册取数能力;query 支持 outputs 与 `result_mode=full |
summary |
scripts/data_grant.py |
register / query / list / revoke / refresh |
数据授权:把一次 fastQuery/stockProfile/selectByComposition 请求钉死成 grant_id+signature,页面免 key 直取有界数据(取舍见「数据授权 vs 公式包」) |
tools/data_grant.md |
scripts/build_dashboard.py |
(单命令,emit:"panel_block" 走局部产出) |
spec → live 实时取数看板 HTML;局部产出模式只生成带 marker 的图表 <script> 片段,供 bespoke 页面内嵌图表用 |
tools/build_dashboard.md |
scripts/stock_comparison.py |
apply @params.json |
为 stock_analysis_instance_v1 原生收盘价图并入基准序列、双 Y 轴和数据表;保持 #priceChart 单一 owner,拒绝用通用 panel 二次接管 |
tools/stock_comparison.md |
scripts/stock_window.py |
apply @params.json |
为 legacy stock_analysis_instance_v1 设置滚动展示窗口;生成受控 HTML 后必须浏览器预检并 update 原 page_id |
tools/stock_window.md |
scripts/chart_edit.py |
inspect / add_series(支持 axis:"right" 双轴)/ remove_series / set_window / query_data |
已发布页面单个图表的增删改查:只动被要求的那一处,不重新验证/计算页面上其它无关系列 | tools/chart_edit.md |
scripts/compile_bespoke_page.py |
(单命令) | 【shell 处理脚本】 bespoke 主体 HTML → 内联公共 share shell / logo / qr-mini / data-kernel 的自包含 HTML | guides/share-shell.md |
scripts/retrofit_share_shell.py |
(单命令) | 【shell 处理脚本】 旧 HTML/已发布页面 → 删除旧二维码/旧页头/旧页尾,套入公共 share shell(assets/share-shell/),可原链接 update |
tools/retrofit_share_shell.md |
scripts/data_kernel_retrofit.py |
(单命令) | 按 QB_DATA_KERNEL marker 或严格旧内核指纹,只替换页面中的 data-kernel;零个/多个命中均拒绝写回 |
tools/data_grant.md |
scripts/static_page.py |
new_asset_page / templates / direct_deliver / new_page / update_progress / publish_final / publish_verified / upload / update / download / image_upload / image_list / fork_prepare / fork_review_update / fork_validate / retrofit_card_runtime / 其他管理命令 |
简单单股快速返回、范式路由、正文图片、direct 确定性交付、首链进度、分级浏览器门禁和页面发布管理 | tools/static_page.md |
scripts/qbs_handoff_adapter.py |
@handoff.json |
校验 QBS computation capsule 的 lineage、合同 fingerprint 与 artifact hash,输出 covered/partial/unusable;不负责路由、ownership、构建或发布 | 本节“从 QBS 并行交接进入” |
scripts/qbs_bridge.py |
resolve_asset_data / <quant-buddy-skill tool> @params.json / validate_package_set / validate_grant_set |
统一实时路由探测并继承 QBV→QBS task_id;按最终 package/Grant 合同生成 route/grant/formula fingerprint 绑定收据 | 本节“新会话路由” |
scripts/publish_workflow.py |
@publish-plan.json |
manifest v2驱动 review/合同预检、package+Grant验证、每role一次注册、多Marker扇出替换和单次 publish_verified;v1 JSON兼容 |
tools/publish_workflow.md |
scripts/validate_agent_reply.py |
(单命令) | 校验发布器 SHA256 绑定的终态 contract 与 Markdown 草稿,并检查公开 URL、章节结构和敏感信息;可在成功后清理任务临时参数文件 | — |
scripts/verify_page.mjs |
(单命令) | 发布前/发布后页面验收:标准三视口、h1、占位符、横向溢出、控制台核心错误;批注迭代可用 --profile ui-refinement、--extra-viewport 与 --min-visible-font-px;范式卡加 --card-runtime 或 --card-runtime-only |
guides/browser-feedback-refinement.md |
assets/data-kernel.js |
(前端内核,非脚本) | 手搓 bespoke 页共用的「取数 + 清洗 + 容错」一份;内联进页面 <script> 用 |
guides/bespoke-page.md |
assets/share-shell/ |
(公共组件) | 所有落地页共用的页头、页尾、刷新按钮、分享海报弹层、海报 canvas、复制链接与复制/下载行为 | guides/share-shell.md |
assets/live-card.css |
(公共组件) | 范式卡 artifact 的浅色卡片样式源;由 build_dashboard.py 作为 data-qb-card-style 内嵌进 card runtime artifact |
guides/essence-cover-card.md |
scripts/card_runtime_retrofit.py |
(被 static_page 调用) | 为已发布/官方精选页重建独立 card runtime artifact(embedded-card-v1),可原链接写回 |
tools/static_page.md |
guides/essence-cover-card.md |
(开发指南) | 页面精华浓缩为独立 4:3 card runtime artifact(embedded-card-v1,空白宿主独立 hydrate),并明确 artifact、范式卡快照与整页封面的职责边界 |
— |
三条生产路:固定页面先复用在线模板;标准看板走
build_dashboard(声明式快路);要自定义版式/SVG 的设计页才写 bespoke 主体 HTML。 stock 原生图表 owner 门禁:stock_analysis_instance_v1的#priceChart始终由页面原生 runtime 持有;禁止用build_dashboard.py emit="panel_block"注入第二个 renderer。增加沪深300等基准线时必须使用scripts/stock_comparison.py扩展原生 load/render/table 生命周期。 stock legacy 时间窗口门禁:stock_analysis_instance_v1缺少QBV_RENDER_JSmarker 时,改窗口必须使用scripts/stock_window.py apply,不要生成或执行output/*.py临时补丁。转换后必须本地浏览器预检、static_page.py update同一页并做公网验收。 数据层统一调assets/data-kernel.js(QB.query取数、QB.series/lastValue/topValues解包清洗),别再每页各抄fetch/解包、各踩"假 0/缺口"的坑。见 guides/bespoke-page.md。 发布前用scripts/verify_page.mjs <html_file> --require-browser检查桌面与 390px/320px 移动端,确保无QB_SHARED_/replace_with_signature/pkg_replace残留、存在<h1>、无关键横向溢出和核心取数脚本错误。页面声明stock_analysis_instance_v1且在data_sources.benchmark_series或comparison.benchmark_series配置基准时,脚本还会在 runtime pending 归零后等待稳定窗口,并强制检查最终 canvas、个股/基准两条有效图表序列、共同交易日、基准右侧 Y 轴、双 Y 轴和数据表列;同时静态拒绝原生 runtime 与 panel_block 共同接管#priceChart。不能只因 runtime ready 或首帧短暂出现就视为对比页已交付。含范式卡 artifact 的页面加--card-runtime(或--card-runtime-only)验收 artifact/manifest/独立 hydrate。Playwright 不在默认 Node 搜索路径时,可用QBV_PLAYWRIGHT_MODULE_ROOT指向包含playwright/的node_modules根目录;可用CHROME_PATH指定浏览器可执行文件,未指定时自动发现 Chrome/Edge。若机器没有 Playwright/Chrome/Edge,脚本会明确标记为static-only,不能当完整浏览器验收。
配置
config.json:填入 api_key(从 https://www.quantbuddy.cn/login 获取)。可建 config.local.json 覆盖 endpoint / api_key 等(不入库)。环境变量 QUANT_BUDDY_API_KEY 仅在 config.json / config.local.json 都没有 api_key 时兜底,不是常规配置方式。本技能所有脚本的 main() 都支持工具调用参数里的 api_key 字段临时覆盖(仅当次调用生效,优先级最高,见 scripts/common.py::configure_trace_context);同一优先级还有环境变量 QBV_API_KEY,用于"手上是一份现成的 @file 参数(比如 publish_workflow.py @publish-plan.json,该 plan 文件按设计不含凭证)、不想现改这份文件塞 api_key"的场景——不要为了临时换 key 去设 QUANT_BUDDY_API_KEY,那个只在 config.json 为空时才生效,config.json 已有默认 key 时设它不会有任何效果。