@viccydev/pi-fpa
v2.3.0
Published
Full-cycle FP&A planning, strategy, forecast, and review prompts, skills, and data tools for Pi
Readme
pi-fpa
面向 Pi 的完整 FP&A 周期资源包,目标运行时为 @earendil-works/pi-coding-agent 0.84.1。
本包分发 Prompt Template、Skill、参考合同,以及 Graph 路由护栏、数据读取、规范化 Artifact 和看板投影四个 Extension。包内不含业务数据与模型凭证,也不实现工作流状态机;它声明并在工具调用边界执行主 Agent 必须遵守的 Graph-first 路由契约。Graph 的定义、状态、多 Agent 隔离、人工审批和真实外部执行仍由宿主运行时或独立工作流承担。
包含的资源
Prompt Template:
/fpa-plan-cycle:通过fpa-strategy-planningGraph 完成 Actuals 诊断、驱动分析、策略模拟、推荐和独立复核,形成reviewed_strategy_handoff后停止;不跨越人工批准或冻结正式预测。/fpa-review-cycle:在精确 Forecast/Execution refs 和新周期 Actuals 到达后,通过fpa-cycle-reviewGraph 形成周期复盘。
Skill:
fpa-apply-core-rulesfpa-plan-cyclefpa-diagnose-actualsfpa-analyze-driversfpa-simulate-strategiesfpa-recommend-strategyfpa-review-strategyfpa-forecast-approved-strategyfpa-review-cyclefpa-execute-approved-strategyfpa-refresh-dashboard
执行 Skill 设置了 disable-model-invocation: true,不会出现在模型可主动调用的 Skill 摘要中,也没有对应 Prompt。它只能由用户显式输入 /skill:fpa-execute-approved-strategy,或由 fpa-strategy-execution Graph 通过插件间注册按名称精确分配;Graph 分配不会把 Skill 暴露给主模型。P1 只解析精确、不可变的执行请求并展示人工执行状态,不调用真实 adapter;缺少 F1 lineage、目标账户、负责人或独立执行授权时必须保持 blocked。
Graph-first 路由
主 Agent 同时具备 graph_list 和 graph_run 时,任何跨两个或更多 FP&A
阶段的请求都必须先查询 Graph catalog,再运行当前第一个满足入口条件的
Graph;在此之前不得调用 fpa_* 工具或写 Artifact。四个工作流的边界为:
fpa-strategy-planning:在一个组合 Graph 中完成规划至reviewed_strategy_handoff后停止。数据/驱动审计与三类策略场景分别并行; 并行子节点只读,正式 Artifact 由后续汇总节点顺序写入。fpa-forecast-freeze:只接受精确 handoff,经人工批准后冻结 Forecast。fpa-strategy-execution:只接受精确 execution request ID 与指纹,由确定性服务校验其 committed F1 lineage、预算、切片、账户、负责人和独立授权;当前模板只记录人工外部执行,不调用投放适配器。fpa-cycle-review:只接受精确 Forecast/Execution refs 与新 Actuals。
Graph 的业务阻塞不能触发父 Agent 降级执行。Graph 工具不可用、catalog 不存在
匹配 Graph 或匹配 Graph 无法加载时,多阶段入口保持 blocked;用户必须另行
显式请求一个隔离阶段,父 Agent 不能自动把完整工作流改成本地串行执行。Graph
节点只执行分配给自己的阶段,不得递归启动另一个 Graph。
fpa-routing-guard Extension 会在 Pi 的 tool_call 执行前落实这条边界:
它从展开后的请求识别多阶段 FP&A 意图,要求目标 Graph 与请求阶段一致,并
阻断父 Agent 的提前 fpa_* 调用和 artifacts/ 写入。Graph worker 没有
graph_list/graph_run 时不会激活该护栏,因此节点仍可执行被分配的单一阶段。
首次在可信项目进入 FP&A 工作流时,护栏会把 package 自带的 Graph 模板安装到
.agent-graph/graphs;较旧的同名模板和已经退役的拆分 Graph 会先移入
.agent-graph/graphs_backup_v* 再更新,因此 graph_list 能直接发现当前组合
Graph,同时保留可恢复的旧定义。非可信项目、符号链接目录和更高版本的项目
Graph 均不会被覆盖。
数据 Extension(fpa-data)
extensions/fpa-data 注册五个只读工具,连接 Supabase 数据集市:
| 工具 | 作用 |
| --- | --- |
| fpa_data_catalog | 数据字典:数据集、维度、指标定义与聚合语义、各表实时日期覆盖、已知数据坑 |
| fpa_query | 结构化聚合查询:指标 + 维度 + 时间粒度 + 过滤;SQL 由代码生成,比率按“先聚合分子分母、再相除”计算 |
| fpa_cohort | 安装 cohort 的 LTV / ROAS / 留存曲线(D0/D3/D7/…),未成熟或缺分母一律返回 NULL 并给出原因 |
| fpa_calc | 确定性计算器:命名公式求值(四则、abs/min/max/round),NULL 与除零安全传播 |
| fpa_compare | 双期间对比:差值、百分比变化、逐行贡献度全部由代码计算 |
fpa_data_catalog 默认只读取数据字典和各数据集日期覆盖,不执行随表规模增长的精确行数扫描。确实需要精确 row_count、App 数量和 cohort-size 覆盖时显式传入 include_stats: true;需要 App 列表时传入 include_apps: true。这些补充信息都有独立的 5 秒预算,单个数据集超时会返回对应的 *_unavailable 说明,不会丢失其它数据集的覆盖信息。认证、网络、服务端错误和调用方取消仍然抛出。
设计契约:模型不写 SQL、不做任何算术。模型只从注册表中选择数据集、指标和维度;SQL 生成、数据库聚合和全部派生计算(比率、差异、LTV/ROAS/留存、临时公式)都在 Extension 代码内完成,缺数据或除零返回 NULL,绝不编造数值。
Extension 内置的关键防护:
appsflyer_ua_campaign_daily的三种breakdown_type是同一份花费的重叠切分;每次查询自动锁定一种,避免花费被重复计算。- 每个查询结果都带
date_min/date_max/source_rows覆盖率元数据;各数据集日期覆盖不一致时以此为准。 - Apple 指标按来源语义聚合:COUNT 求和、AVERAGE 取日均、LATEST 取期末值。
- cohort 规模缺失(2026-08-01 之前)时 LTV/留存分母返回 NULL。
Artifact 与看板 Extension
fpa-artifacts 提供 fpa_forecast_finalize,把紧凑 Forecast plan 一次性合成、校验、按目标周期推导生命周期角色并冻结;模型无需在 Graph handoff 与 ledger 枚举之间转译 forecast_role。通用的 fpa_artifact_commit 仍负责 approved_cycle_forecast 和 execution_receipt 的严格字段校验、对账、稳定指纹和原子落盘。只有工具返回成功后的 JSON 才是冻结产物,Markdown 不是正式数据源。
fpa-execution 的确定性服务提供执行请求准备、独立授权和整体人工回执;Agent Extension 只暴露状态读取、精确请求解析和 execution-evidence 发布工具,不能伪造登录用户的写入身份。执行请求与回执 append-only;重复提交使用稳定提交 ID 幂等恢复。人工回执始终是 reported / complete_with_limits,实际支出、applied mutations、外部回执和核验证据保持空值。Backtest 模式禁止创建上述对象。
同一 Extension 还提供 fpa_evolution_evaluate:对已经关闭且可比较的 Forecast 方法确定性计算 WAPE、MAPE、Bias、区间覆盖率和相对 baseline 改善;对分析 Playbook 计算客观检查通过率与耗时改善。工具只输出 fpa-evolution-evidence/v1 证据及其生命周期策略,不直接改变 Agent,也不会凭一次结果宣布方法更优。调用方必须提供 kind:sha256:<64hex> 格式的精确 Forecast/Actuals 或分析/review 引用和 period_end;缺少完整预测区间、baseline、有效分母或历史时点证明时会返回不足证据。
fpa-dashboard 提供分模块发布工具和兼容的闭环刷新工具:
| 工具 | 作用 |
| --- | --- |
| fpa_dashboard_module_status | 只读检查各独立模块及当前 Dashboard revision |
| fpa_dashboard_publish_review | 只发布 period-review,保留其他模块 |
| fpa_dashboard_publish_strategy | 只发布带确认/修改动作的 next-strategy,并绑定当前主会话 |
| fpa_dashboard_publish_forecast | 确认策略并冻结预测后,只发布 next-forecast |
| fpa_dashboard_status | 只读检查当前 manifest、构建回执和各数据集是否可读 |
| fpa_dashboard_refresh | 从冻结预测、可选执行回执和实时 Actuals 生成固定的闭环看板;先 preview,再携带相同指纹原子 publish |
| fpa_dashboard_refresh_queue | 检查或处理持久刷新队列;主 Agent 用 enqueue_artifact 显式交接 Forecast/Execution,Actuals watermark 按 SLA 轮询并幂等发布 |
持续刷新由 package 自带的独立 worker 驱动,Web 保持严格只读:
fpa-dashboard-worker --workspace /absolute/path/to/workspace使用 --once 可接 cron/systemd timer;常驻运行时默认每 30 秒检查队列,并按内部 5 分钟 Actuals 水位 SLA 轮询。worker 只消费精确 immutable artifact refs,执行有界重试,并通过与交互工具相同的原子 publisher 发布。
周期关账不按“过了若干小时”推断。ETL 必须原子写入一份有界、非 group/world-writable 的 JSON 关账信号,并同时配置 FPA_ACTUALS_CLOSE_SIGNAL_PATH 与 FPA_ACTUALS_CLOSE_SIGNAL_ROOT。可信根必须位于 Agent workspace 之外,且文件及其目录链必须由 Agent 运行身份之外的控制面身份拥有;否则 worker 会拒绝把周期判为已关账:
{"kind":"fpa.actuals.source-close","schema_version":1,"dataset":"ua_spend","signal_id":"ua-close-2026-08-v1","closed_through":"2026-08-31","emitted_at":"2026-09-01T03:00:00Z"}缺少该信号时,完整日期覆盖仍只算累计 Actual,不开放整周期 Forecast vs Actual 差异。
看板按 app_id + store + channel_group 精确限定同口径 Actuals,比率全部在聚合后重算,缺值保持 NULL;未获批的付费分片只形成告警,不混入预测对比。整周期 Forecast vs Actual 只在 Actuals 提供统一、完整、可勾稽的单快照,且比较基线是周期开始前冻结的 original Forecast 时开放;EAC、稀疏覆盖和多查询未核验快照都不会生成伪差异。发布器写内容寻址的数据集、不可变 generation catalog,并最后原子提升 manifest.json,不会让 Web 端读到半成品代际。
凭证配置
Extension 通过 Supabase Management API 只读查询,凭证仅从环境变量读取,绝不写入包内:
export SUPABASE_PROJECT_REF="<project ref>"
export SUPABASE_ACCESS_TOKEN="<personal access token, sbp_...>"在启动 Pi 前设置。未配置时工具报错并说明缺哪个变量,不发出任何查询。
Backtest 启动模式
回测必须在启动 Pi 前显式配置,不能只在提示词或 Graph 中把 forecast_role 写成 backtest:
export FPA_RUN_MODE="backtest"
export FPA_EFFECTIVE_AT="2026-05-01T00:00:00Z"默认回测直接复用现有 SUPABASE_PROJECT_REF 和
SUPABASE_ACCESS_TOKEN,但所有查询都会被截断到 FPA_EFFECTIVE_AT
对应的业务日期。启动后 RunProfile 不可热切换;推进模拟时间必须停止并
重启进程。例如先在 5 月 1 日冻结 Forecast,周期结束后改为 6 月 1 日,
再用原 Forecast 的精确 ref 运行 fpa-backtest-review。
如需严格无回刷证据,可额外启用高级快照模式:
export FPA_DATA_SNAPSHOT_REF="kind:sha256:<64 lowercase hex>"
export FPA_BACKTEST_SUPABASE_PROJECT_REF="<isolated snapshot project ref>"
# 默认复用 SUPABASE_ACCESS_TOKEN;快照项目使用单独凭证时设置:
export FPA_BACKTEST_SUPABASE_ACCESS_TOKEN="<snapshot access token>"
# 查询 CSV 数据集时还必须设置:
export FPA_BACKTEST_CSV_ROOT="/absolute/path/to/immutable/snapshot/csv"启动配置会形成不可变 RunProfile。Backtest 模式下:
effective_at是模拟的历史决策时点;普通查询、Catalog 和 Cohort 都会被截断到该日期。- 默认
live_cutoff模式读取现有 Supabase;它适合流程调试和业务复盘,但可能看到后来补录或重算的历史数据,因此不是严格无泄漏证据。 live_cutoff模式允许为当前effective_at手动上传回测专用财务 CSV。上传人必须确认该版本在模拟时点已经存在;版本按模拟时点隔离,不读取或覆盖经营模式上传,且不能包含当时尚未完成的月份。- 同时提供 snapshot ref 和独立项目时进入
immutable_snapshot模式;该 project ref 不得与正式库相同。严格 CSV 快照使用FPA_BACKTEST_CSV_ROOT。 immutable_snapshot模式保持只读,不接受页面上传。- Forecast 的生命周期角色仍相对
effective_at推导。例如在 5 月回测“6 月计划”时,run_mode=backtest、forecast_role=next_plan。 - Forecast 正文和 Ledger 同时记录 RunProfile、快照引用与生命周期角色;调用方提供的
frozen_at仍会被忽略。 - 规划完成后与经营模式一致,由
fpa_dashboard_publish_review和fpa_dashboard_publish_strategy发布复盘与策略模块;人工确认仍由fpa_strategy_decision_commit固化,随后发布只读next-forecast。 - 回测允许继续生成执行计划、完成独立执行授权、提交人工回执,并发布
execution-evidence。这些记录使用FPA_EFFECTIVE_AT作为业务时间,修改模拟时间并重启后仍沿同一回测时间线继续;旧版按单一时点保存的计划会无损迁移。 - 回测执行仅用于完整流程调试:不会调用真实投放平台。完整闭环刷新、通知、真实投放及经营 current pointer 更新仍被阻断,人工回执继续明确标记为未经过外部核验。
FPA_DATA_SNAPSHOT_REF 是可选的内容寻址快照身份;一旦设置,必须同时设置独立 snapshot project。仅按日期读取持续回刷的正式 Mart 不构成严格无泄漏回测。正式模式下不要残留上述 Backtest 变量,否则启动配置会拒绝加载。
输入契约
两个 Prompt 的基本参数都是:
<project-root> <cycle-id> [instructions]数据来源优先级:
fpa_data_catalog等fpa_*工具(Supabase 集市,推荐)。- 运行时显式提供的字段目录与 Schema 路径。
<project-root>/LOCAL_FPA_MART_FIELD_CATALOG.md与<project-root>/LOCAL_FPA_MART_SCHEMA.sql(本地文件回退)。
资源不存在时必须报告缺口,不得回退到开发者机器路径或编造输入。
本地安装
从 npm 安装正式版本:
pi install npm:@viccydev/pi-fpa从本地工作区安装开发版本:
pi install /absolute/path/to/pi-fpa
pi list本地路径只写入 Pi settings,不复制源目录。修改包后使用 /reload 或重启 Pi。
团队分发建议使用固定 Git tag:
pi install git:github.com/linyqh/[email protected]发布到 npm
发布动作由 GitHub Release 触发。Release 标签必须严格使用 v<package.json version>,例如版本 1.1.0 对应 v1.1.0。工作流会检出该标签,执行 npm ci、npm test 和包内容预检,全部通过后发布公开包 @viccydev/pi-fpa。普通 Release 发布到 latest,Prerelease 发布到 next。
发布认证使用 npm Trusted Publishing / OIDC,不使用长期 npm Token。npm 包后台的 Trusted Publisher 配置为:
- Provider:GitHub Actions。
- Organization or user:
linyqh。 - Repository:
pi-fpa。 - Workflow filename:
publish.yml。 - Allowed actions:
npm publish。
工作流必须保留 permissions.id-token: write,并使用满足 npm Trusted Publishing 最低版本要求的 Node/npm;不要重新添加 NPM_TOKEN 或 NODE_AUTH_TOKEN。当前 GitHub 仓库为 private,OIDC 发布可用,但 npm 不会生成 provenance。当前许可证仍是 UNLICENSED;若准备让第三方使用或修改本包,应先明确许可证。
使用
/fpa-plan-cycle /path/to/project 2026-Q3 "按 App、Store、Channel Group 规划;预算上限见 planning input"
/fpa-review-cycle /path/to/project 2026-Q3 "使用精确 forecast/execution refs 和新到达的 Actuals snapshot"
/skill:fpa-refresh-dashboard "预览并发布当前项目的预测闭环看板"规划入口停在 reviewed_strategy_handoff,不会等待人工批准、冻结 Forecast 或进入真实策略执行。后续分别由 fpa-forecast-freeze 和 fpa-strategy-execution Graph 承担。若宿主没有 Graph 能力、且用户只请求一个隔离执行阶段,才可在单独、已授权的运行中显式调用:
/skill:fpa-execute-approved-strategy <exact committed forecast ref and execution scope>资源迁移注意
如果 ~/.pi/agent/skills/ 中仍有同名 fpa-* Skill,Pi 会报告命名冲突并采用先发现的资源。先在隔离配置中验证本包,确认来源路径后再通过 pi config 禁用旧副本或将旧目录移出发现路径。全局 ~/.pi/agent/extensions/ 下如有旧的数据 extension(如 ios-fpa),工具名不同不会冲突,但建议确认是否仍需保留。
验证
npm test # 包结构 + extension 单元测试 + Pi loader 冒烟
npm run test:live # 可选:需要 SUPABASE_* 环境变量,对真实库做只读冒烟
npm run pack:check数据口径自动发现(1.3.0)
data-rules-2 在原有数据服务内增加只读元数据发现,页面与 fpa_check_data 共用结果;fpa_data_catalog 也返回 source_discovery。兼容 v1 契约,新增 DataSourceInfo.discovery 和 CheckReport.discovery,没有新增工具参数或数据库迁移。
- 通过
pg_constraint读取已验证的业务主键/唯一键。只接受真实存在、符合标识符规则、包含业务日期及 App 身份的字段组合,技术自增 ID 不会被当作业务粒度。服务端明确配置的业务键保留优先级。 - 读取
app_registry的当前有效 App/平台清单及未映射数量。清单限 2,000 对并标注截断;只在一次请求内复用查询。当前注册清单不自动转为某历史月份、某数据源的expectedApps,也不承诺逐日出数。 - 对所选记录单独检查 NULL、空字符串和非法 App 代码。这些记录不计入 App 数量。逐日覆盖按 App/平台分别统计,不允许两个平台的缺天相互抵消。与当前注册表的差异只报告待核对,避免把历史退役/改名误判为漏数。
- 投放花费的 USD 从
cost_usd明确的currency=USD字段说明发现;事件/cohort 金额从四个注册金额字段的 USD 说明发现。AppsFlyer 业务时区从本次选中记录的app_timezone验证;Mixpanel UTC 从business_date的明确说明发现。数据库会话时区不会充当业务时区,不跨表猜测 Master API 或 Apple 报表时区。 - 同一范围出现混合时区或与人工声明冲突时不通过。产品行为来源时区不同会明确排除直接跨来源按日比较;各来源仍可独立检查。
- 使用实时数据加业务日期截止的回测,在投放就绪检查中还检查
source_data_as_of和exported_at。晚于有效时点的版本不可用,证据缺失返回未确认;不能把后来累计的 LTV 或修订值视为过去已知。配置的不可变快照保持原有独立来源路径。 - 查询失败、权限不足、证据缺失不被转换为零或通过。数据库约束发现失败时仍支持明确的服务端声明;登记表不可读不影响 CSV。所有发现包含查询时间、来源和证据,性质
nature和出数承诺recording不会根据表名、行数或日期连续性自动填为真实/完整。
discovery 是本次检查的元数据证据,不是原始数据快照。字段说明和人工声明也不等于外部凭证审计。本轮加强的是数据就绪服务;现有 fpa_query 的业务日期截断不能单独证明当时可知,Agent 应先读 fpa_check_data 的限制,历史复盘需使用符合时点的源版本。
验证覆盖约束发现、空 App、跨平台缺天、时区冲突、登记表不可用/截断、无效证据、并发请求隔离和回测晚到版本。兼容目标为 Pi 0.84.1;包结构依据 Pi package 文档,保持现有 Extension 注册方式。
映射缺口容忍(data-rules-4)
局部 App 映射缺口不再一律阻断后续分析。若每项受检指标的缺失影响都有可靠证据且均不超过 5%,基础指标保留为 usable_with_limits,报告同时排除未映射记录的 App 级归因。影响未知、证据不可靠或任一指标超过阈值时仍保持 unusable;整表缺失、关键值异常、重复记录和回测时点穿越也不受此规则放宽。
