@viccydev/pi-fpa 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +135 -0
  2. package/extensions/fpa-data/calc.ts +544 -0
  3. package/extensions/fpa-data/index.ts +478 -0
  4. package/extensions/fpa-data/registry.ts +303 -0
  5. package/extensions/fpa-data/sql.ts +412 -0
  6. package/extensions/fpa-data/supabase.ts +96 -0
  7. package/package.json +54 -0
  8. package/prompts/fpa-plan-cycle.md +44 -0
  9. package/prompts/fpa-review-cycle.md +33 -0
  10. package/skills/fpa-analyze-drivers/SKILL.md +30 -0
  11. package/skills/fpa-analyze-drivers/references/artifact-contract.md +34 -0
  12. package/skills/fpa-apply-core-rules/SKILL.md +34 -0
  13. package/skills/fpa-apply-core-rules/references/core-rules.md +96 -0
  14. package/skills/fpa-diagnose-actuals/SKILL.md +30 -0
  15. package/skills/fpa-diagnose-actuals/references/artifact-contract.md +38 -0
  16. package/skills/fpa-execute-approved-strategy/SKILL.md +40 -0
  17. package/skills/fpa-execute-approved-strategy/references/artifact-contract.md +29 -0
  18. package/skills/fpa-forecast-approved-strategy/SKILL.md +39 -0
  19. package/skills/fpa-forecast-approved-strategy/references/artifact-contract.md +36 -0
  20. package/skills/fpa-plan-cycle/SKILL.md +29 -0
  21. package/skills/fpa-plan-cycle/references/artifact-contract.md +41 -0
  22. package/skills/fpa-recommend-strategy/SKILL.md +29 -0
  23. package/skills/fpa-recommend-strategy/references/artifact-contract.md +30 -0
  24. package/skills/fpa-review-cycle/SKILL.md +32 -0
  25. package/skills/fpa-review-cycle/references/artifact-contract.md +30 -0
  26. package/skills/fpa-review-strategy/SKILL.md +28 -0
  27. package/skills/fpa-review-strategy/references/artifact-contract.md +25 -0
  28. package/skills/fpa-simulate-strategies/SKILL.md +32 -0
  29. package/skills/fpa-simulate-strategies/references/artifact-contract.md +35 -0
@@ -0,0 +1,34 @@
1
+ # `driver_analysis` contract
2
+
3
+ ```yaml
4
+ artifact_type: driver_analysis
5
+ status: complete | complete_with_limits | blocked
6
+ planning_brief_id: string
7
+ actuals_snapshot_id: string
8
+ comparison_basis: string
9
+ headline_results:
10
+ - metric: string
11
+ actual: number | null
12
+ baseline: number | null
13
+ variance: number | null
14
+ variance_pct: number | null
15
+ drivers:
16
+ - rank: integer
17
+ name: string
18
+ type: volume | rate | efficiency | mix | coverage | external | unknown
19
+ controllable: boolean
20
+ affected_metrics: []
21
+ quantified_contribution: number | null
22
+ evidence: []
23
+ confidence: high | medium | low
24
+ bridges:
25
+ - metric: string
26
+ total_change: number
27
+ explained_change: number
28
+ residual: number
29
+ method: string
30
+ hypotheses_to_test: []
31
+ data_limits: []
32
+ ```
33
+
34
+ The bridge is invalid if its contributions plus residual do not reconcile to total change within the stated rounding tolerance.
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: fpa-apply-core-rules
3
+ description: Apply the shared period, source-grain, metric, quality, approval, and artifact rules for this project's FP&A and UA workflows. Use for any FP&A planning, actuals diagnosis, driver analysis, strategy simulation, recommendation, review, approved forecast, execution, or next-cycle variance review.
4
+ ---
5
+
6
+ # FP&A Core Rules
7
+
8
+ Use this skill together with the phase-specific FP&A skill. It is the common contract, not a complete workflow by itself.
9
+
10
+ ## Required procedure
11
+
12
+ 1. Read [core-rules.md](references/core-rules.md) before calculating or judging anything.
13
+ 2. Identify the workflow phase and consume only artifacts that precede it.
14
+ 3. Bind the requested business period to exact start and end timestamps, timezone, currency, App, Store, and Channel scope.
15
+ 4. Check that every source grain can support the requested period. Never manufacture finer-grained results by prorating coarse facts.
16
+ 5. Separate observed facts, assumptions, calculations, judgments, and approvals in the output.
17
+ 6. Preserve lineage: record `data_as_of`, source versions, assumption version, model version, and upstream artifact IDs when available.
18
+ 7. Fail closed when required data, maturity, approval, or execution authority is missing.
19
+
20
+ ## Non-negotiable boundaries
21
+
22
+ - Use “周期” as the general planning unit; do not silently assume a month.
23
+ - Treat the mart datasets (Supabase via the `fpa_*` tools, or the local Mart files fallback) as Actuals, not as a budget, forecast, scenario, or approval ledger.
24
+ - Route every calculation through deterministic code: `fpa_query`/`fpa_cohort`/`fpa_compare` for aggregation and `fpa_calc` for ad-hoc formulas. Never perform arithmetic in model output.
25
+ - Aggregate additive numerators and denominators first, then recompute ratios.
26
+ - Return `NULL` for missing, immature, or zero-denominator metrics; never convert them to zero.
27
+ - Keep pre-approval scenario simulation separate from the official post-approval forecast.
28
+ - A recommendation agent cannot approve its own proposal. Human approval is external and explicit.
29
+ - Do not continuously monitor execution. Review only when the next cycle's data snapshot arrives.
30
+ - Do not mutate source facts or claim that an external campaign change occurred without a real authorized adapter receipt.
31
+
32
+ ## Completion check
33
+
34
+ Before handing off, name the produced artifact, its status, the next eligible skill, and every blocker. Do not skip an approval gate by routing directly from recommendation to official forecast or execution.
@@ -0,0 +1,96 @@
1
+ # Shared FP&A contract
2
+
3
+ ## 1. Workflow and artifacts
4
+
5
+ Planning workflow:
6
+
7
+ `planning_brief -> actuals_snapshot + data_issue_report -> driver_analysis -> strategy_scenarios -> strategy_proposal -> strategy_review -> human strategy_approval -> approved_cycle_forecast`
8
+
9
+ The planning workflow ends after the approved forecast is frozen.
10
+
11
+ Execution is a separate workflow:
12
+
13
+ `strategy_approval + strategy_proposal -> execution_receipt`
14
+
15
+ Next-cycle review is another workflow, triggered only after new Actuals arrive:
16
+
17
+ `approved_cycle_forecast + next actuals_snapshot -> cycle_review -> optional new planning_brief`
18
+
19
+ Artifact ownership belongs to the workflow runtime or artifact store. An agent produces content and metadata; it must not invent a successful save, approval, or external action.
20
+
21
+ ## 2. Period and source grain
22
+
23
+ The business period can be a week, two weeks, a month, or another explicit interval. Every run must bind:
24
+
25
+ - period ID, start inclusive, end exclusive, and business timezone;
26
+ - comparison baseline and its exact interval;
27
+ - reporting currency;
28
+ - App, Store, Product Group, and Channel Group scope;
29
+ - `data_as_of` cutoff.
30
+
31
+ A requested period is calculable only when its boundaries and the relevant source grain permit exact aggregation. Do not divide coarse facts into finer periods. Mark unsupported metrics unavailable or request a finer-grained source. Source grain and date coverage differ per dataset; read them from the data authority below instead of assuming them.
32
+
33
+ Project data authority is supplied by the caller and is never embedded as a developer-machine absolute path. Resolve it in this order:
34
+
35
+ 1. The `fpa_*` data tools from the `fpa-data` extension when they are loaded and credentialed: `fpa_data_catalog` is the field catalog and live-coverage authority; `fpa_query`, `fpa_cohort`, and `fpa_compare` are the query paths.
36
+ 2. Explicit field-catalog and schema paths supplied for the run.
37
+ 3. `<project-root>/LOCAL_FPA_MART_FIELD_CATALOG.md` and `<project-root>/LOCAL_FPA_MART_SCHEMA.sql`.
38
+
39
+ For file-based authorities, verify the files exist before relying on them. If no authority is available, report the missing input and return `blocked` for claims that depend on it; do not silently fall back to another project or remembered schema.
40
+
41
+ ## 3. Metric rules
42
+
43
+ Every number must be produced by deterministic code, never by model arithmetic. Aggregation and ratios come from `fpa_query`, cohort curves from `fpa_cohort`, period deltas from `fpa_compare`, and any remaining ad-hoc formula (variance, growth, run-rate, budget split) from `fpa_calc`. If the tools are unavailable, numbers may only be copied verbatim from a verified source; a metric that would require mental math is `NULL` with a named gap.
44
+
45
+ Additive measures may be summed only after App, Store, Channel, timezone, currency, attribution, and period mappings are aligned.
46
+
47
+ Recompute ratios from aggregated components:
48
+
49
+ ```text
50
+ CPI = SUM(spend) / NULLIF(SUM(paid_installs), 0)
51
+ CAC = SUM(spend) / NULLIF(SUM(attributed_new_paid_users), 0)
52
+ retention_dN = SUM(retained_users_dN) / NULLIF(SUM(cohort_size), 0)
53
+ paid_rate_dN = SUM(new_paid_users_dN) / NULLIF(SUM(cohort_size), 0)
54
+ observed_ltv_dN = SUM(net_proceeds_dN_amount) / NULLIF(SUM(cohort_size), 0)
55
+ cost_per_first_open = SUM(cohort_spend_amount) / NULLIF(SUM(cohort_size), 0)
56
+ cohort_cac_dN = SUM(cohort_spend_amount) / NULLIF(SUM(new_paid_users_dN), 0)
57
+ observed_roas_dN = SUM(net_proceeds_dN_amount) / NULLIF(SUM(cohort_spend_amount), 0)
58
+ ```
59
+
60
+ Never average precomputed CPI, CAC, retention, paid rate, LTV, or ROAS across groups.
61
+
62
+ Useful planning identities, applied only when components are comparable:
63
+
64
+ ```text
65
+ paid_installs = spend / CPI
66
+ new_paid_users = paid_installs * paid_rate
67
+ cohort_net_proceeds_dN = cohort_size * observed_ltv_dN
68
+ observed_roas_dN = cohort_net_proceeds_dN / cohort_spend
69
+ variance = actual - frozen_forecast
70
+ variance_pct = variance / NULLIF(ABS(frozen_forecast), 0)
71
+ ```
72
+
73
+ These are identities, not causal models. Forecasting a changed spend level requires an explicit response/elasticity assumption; historical average efficiency alone is insufficient.
74
+
75
+ ## 4. Data quality and maturity
76
+
77
+ - Preserve the natural key `(cohort_week, app_id, store, channel_group)` for Cohort Spend joins.
78
+ - Aggregate Spend to the natural key before joining; never duplicate monthly Spend across cohort weeks.
79
+ - Align First Open attribution and Spend on App, Store, Channel Group, business timezone, and attribution window.
80
+ - Treat paid-channel Spend missing or unreconciled as `NULL`; only Organic Spend is structurally zero.
81
+ - Treat unmatured D7, D30, and D90 cohort observations as `NULL`.
82
+ - Do not use `UNATTRIBUTED` cohorts for channel-return claims until Spend is reliably assigned.
83
+ - Record exclusions and reconciliation gaps; do not silently impute them.
84
+
85
+ ## 5. Modeling and governance
86
+
87
+ - Show base, downside, and upside ranges or another explicitly defined uncertainty method.
88
+ - Keep assumptions separate from observed values and attach an owner/source to each material assumption.
89
+ - Do not extrapolate beyond historical support without naming and stress-testing the extrapolation.
90
+ - Prefer marginal return estimates for reallocation; label average ROAS as descriptive, not marginal.
91
+ - Freeze the approved strategy, approval evidence, data snapshot, assumptions, and model version before official forecasting.
92
+ - Compare future Actuals with that frozen forecast, never with a forecast regenerated after outcomes are known.
93
+
94
+ ## 6. Output status vocabulary
95
+
96
+ Use one of: `complete`, `complete_with_limits`, or `blocked`. Review opinions use `support`, `support_with_conditions`, or `reject`. Only the external human approval artifact may use `approved`.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: fpa-diagnose-actuals
3
+ description: Validate the FP&A mart datasets and determine which Actuals are safe for a requested business period and decision scope. Use before driver analysis, forecasting, or cycle review, especially when checking grain, completeness, maturity, reconciliation, or join safety.
4
+ ---
5
+
6
+ # FP&A Actuals Diagnosis
7
+
8
+ Load `$fpa-apply-core-rules` first. This is a read-only quality gate.
9
+
10
+ ## Procedure
11
+
12
+ 1. Read the frozen `planning_brief` or review-period contract.
13
+ 2. Inspect the data authority actually available: start with `fpa_data_catalog` (datasets, metric semantics, live date coverage, caveats) when the data tools are loaded, otherwise the field catalog and schema files.
14
+ 3. Check required tables, fields, natural-key uniqueness, nullability, currency, timezone, `data_as_of`, and `aggregation_version`.
15
+ 4. Test whether the source grain exactly supports the requested period. Never prorate monthly facts into weekly or two-week Actuals.
16
+ 5. Check coverage and reconciliation by App, Store, Channel Group, and period.
17
+ 6. Check identity-dependent fields and D7/D30/D90 cohort maturity.
18
+ 7. Produce both `actuals_snapshot` eligibility metadata and `data_issue_report` using [artifact-contract.md](references/artifact-contract.md).
19
+
20
+ ## Classification
21
+
22
+ - `usable`: safe for the stated metric and scope.
23
+ - `usable_with_limits`: safe only after named exclusions or for a narrower claim.
24
+ - `unusable`: missing, incompatible, duplicated, unreconciled, or immature.
25
+
26
+ Do not “repair” a failed metric with undocumented imputation. A quality issue may narrow downstream analysis without blocking every other metric.
27
+
28
+ ## Handoff
29
+
30
+ Pass eligible facts and explicit exclusions to `$fpa-analyze-drivers`. If no metric supporting the primary objective remains usable, return `blocked`.
@@ -0,0 +1,38 @@
1
+ # Actuals diagnosis contracts
2
+
3
+ `actuals_snapshot` records the query boundary and eligible facts; it is not a copied ledger.
4
+
5
+ ```yaml
6
+ artifact_type: actuals_snapshot
7
+ status: complete | complete_with_limits | blocked
8
+ planning_brief_id: string
9
+ period: {start_inclusive: timestamp, end_exclusive: timestamp, timezone: string}
10
+ data_as_of: timestamp
11
+ sources:
12
+ - table: string
13
+ grain: string
14
+ aggregation_version: string
15
+ query_or_snapshot_id: string
16
+ eligibility:
17
+ - metric: string
18
+ scope: string
19
+ classification: usable | usable_with_limits | unusable
20
+ reason: string
21
+ excluded_slices: []
22
+ ```
23
+
24
+ ```yaml
25
+ artifact_type: data_issue_report
26
+ status: complete | complete_with_limits | blocked
27
+ checks:
28
+ - check: string
29
+ result: pass | warn | fail
30
+ affected_metrics: []
31
+ affected_scope: []
32
+ evidence: string
33
+ remediation: string
34
+ blocking_issues: []
35
+ non_blocking_limits: []
36
+ ```
37
+
38
+ Minimum checks: period/grain compatibility, natural-key uniqueness, missing periods, currency consistency, negative/impossible counts, Spend reconciliation, identity coverage, cohort maturity, `data_as_of`, and version presence.
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: fpa-execute-approved-strategy
3
+ description: Execute a human-approved UA strategy through a declared external adapter with strict authorization, version, scope, dry-run, idempotency, and receipt checks. Use only for a separately authorized execution workflow; otherwise fail closed and make no external changes.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # FP&A Controlled Strategy Execution
8
+
9
+ Load `$fpa-apply-core-rules` first. This skill is intentionally fail-closed and is not part of the planning workflow.
10
+
11
+ ## Mandatory entry gate
12
+
13
+ Require all of the following before any external mutation:
14
+
15
+ - explicit human `strategy_approval` for the exact `strategy_proposal` version;
16
+ - exact target accounts, App, Store, Channel, budget, period, and permitted operations;
17
+ - a named, currently available execution adapter/tool and its authentication context;
18
+ - a user-authorized execution request, not merely an approval to forecast;
19
+ - an idempotency key or adapter-supported equivalent;
20
+ - a successful read-only preflight and, where supported, dry-run/preview.
21
+
22
+ If any requirement is missing, return `blocked` and make no external call. Never simulate an adapter or fabricate a receipt.
23
+
24
+ ## Procedure
25
+
26
+ 1. Reconcile the approved allocation with requested external targets.
27
+ 2. Read current external state and detect stale assumptions, duplicate execution, or conflicting changes.
28
+ 3. Generate the exact proposed mutation set and validate limits.
29
+ 4. Present or record the dry-run result when the adapter supports it.
30
+ 5. Execute only the approved mutation set.
31
+ 6. Read back the resulting state and reconcile it with the requested state.
32
+ 7. Write `execution_receipt` using [artifact-contract.md](references/artifact-contract.md).
33
+
34
+ ## Stop conditions
35
+
36
+ Stop before or during execution on version mismatch, target ambiguity, budget mismatch, authentication failure, stale external state, partial failure, or unexpected adapter behavior. Do not broaden scope to “finish” the task.
37
+
38
+ ## Boundary
39
+
40
+ Execution ends after reconciliation and receipt. Do not continuously monitor performance. Performance review begins only when the next cycle's Actuals arrive and uses `$fpa-review-cycle`.
@@ -0,0 +1,29 @@
1
+ # `execution_receipt` contract
2
+
3
+ ```yaml
4
+ artifact_type: execution_receipt
5
+ status: complete | complete_with_limits | blocked
6
+ strategy_version: string
7
+ human_approval_id: string
8
+ execution_request_id: string
9
+ adapter: string
10
+ target_accounts: []
11
+ idempotency_key: string
12
+ preflight:
13
+ result: pass | fail
14
+ observed_state_fingerprint: string
15
+ dry_run:
16
+ supported: boolean
17
+ result: pass | fail | not_supported
18
+ requested_mutations: []
19
+ applied_mutations: []
20
+ failed_mutations: []
21
+ reconciliation:
22
+ result: pass | partial | fail
23
+ resulting_state_fingerprint: string | null
24
+ external_receipt_ids: []
25
+ executed_at: timestamp | null
26
+ blockers: []
27
+ ```
28
+
29
+ Only adapter responses may populate `applied_mutations`, external receipt IDs, and resulting-state evidence. A blocked receipt must have no applied mutations.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: fpa-forecast-approved-strategy
3
+ description: Produce and freeze the official operating forecast for the next business period from one explicitly human-approved UA strategy. Use after independent review and human approval; do not use for candidate scenario trial calculations.
4
+ ---
5
+
6
+ # FP&A Approved Strategy Forecast
7
+
8
+ Load `$fpa-apply-core-rules` first. This is the final stage of the planning workflow.
9
+
10
+ ## Entry gate
11
+
12
+ Require all of the following:
13
+
14
+ - the exact `strategy_proposal` version;
15
+ - a completed independent `strategy_review` supporting that version;
16
+ - explicit human `strategy_approval` identifying the same version and any conditions;
17
+ - the eligible data snapshot, assumptions, and model version used for forecasting.
18
+
19
+ If approval evidence is absent, ambiguous, expired, conditional but unmet, or refers to another strategy version, return `blocked` without forecasting.
20
+
21
+ ## Procedure
22
+
23
+ 1. Verify approval and artifact lineage.
24
+ 2. Lock the approved allocation and all approval conditions.
25
+ 3. Recalculate future-period operating outcomes from that allocation using the declared model.
26
+ 4. Provide downside, base, and upside values for each supported KPI.
27
+ 5. Reconcile allocation totals, formulas, and cross-metric identities.
28
+ 6. Freeze the forecast inputs and write `approved_cycle_forecast` using [artifact-contract.md](references/artifact-contract.md).
29
+
30
+ ## Boundaries
31
+
32
+ - Do not optimize, revise, or substitute the approved strategy while forecasting.
33
+ - A required change invalidates the current approval and routes back to recommendation and review.
34
+ - Unsupported KPIs remain `NULL` with a reason.
35
+ - Do not execute the strategy and do not start continuous monitoring.
36
+
37
+ ## Completion
38
+
39
+ The planning workflow ends after this artifact is durably frozen by the runtime. Execution, if requested, is a separate workflow using `$fpa-execute-approved-strategy`. Review waits for the next cycle's Actuals and uses `$fpa-review-cycle`.
@@ -0,0 +1,36 @@
1
+ # `approved_cycle_forecast` contract
2
+
3
+ ```yaml
4
+ artifact_type: approved_cycle_forecast
5
+ status: complete | complete_with_limits | blocked
6
+ forecast_version: string
7
+ strategy_version: string
8
+ strategy_review_id: string
9
+ human_approval_id: string
10
+ approval_conditions_satisfied: boolean
11
+ target_period: {start_inclusive: timestamp, end_exclusive: timestamp, timezone: string}
12
+ data_as_of: timestamp
13
+ source_snapshot_ids: []
14
+ assumption_version: string
15
+ model_version: string
16
+ reporting_currency: string
17
+ approved_allocation: []
18
+ forecast_by_slice:
19
+ - app_id: string
20
+ store: string
21
+ channel_group: string
22
+ metrics:
23
+ metric_name:
24
+ downside: number | null
25
+ base: number | null
26
+ upside: number | null
27
+ unit: string
28
+ window: string
29
+ consolidated_forecast: {}
30
+ unsupported_metrics: []
31
+ reconciliation_checks: []
32
+ frozen_at: timestamp
33
+ immutable_fingerprint: string
34
+ ```
35
+
36
+ The runtime supplies or verifies the immutable fingerprint. The agent must not claim the artifact is frozen until storage confirms it.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: fpa-plan-cycle
3
+ description: Convert a business objective into a bounded FP&A and UA planning brief for one configurable business period. Use when starting a planning cycle, changing targets or constraints, or deciding what the downstream analysis and recommendation must optimize.
4
+ ---
5
+
6
+ # FP&A Cycle Planning
7
+
8
+ Load `$fpa-apply-core-rules` first. Produce the goal contract that every downstream agent uses.
9
+
10
+ ## Procedure
11
+
12
+ 1. Read the request and available prior `cycle_review` artifact.
13
+ 2. Define the period with exact dates and timezone; never infer “monthly”.
14
+ 3. State the decision to be made, controllable UA levers, and non-controllable assumptions.
15
+ 4. Establish baseline, target metrics, priorities, budget ceiling/floor, and risk guardrails.
16
+ 5. Define the dimensions where a decision is allowed: App, Store, Channel Group, and any supported sub-dimension.
17
+ 6. Check metric feasibility against current source grain and live coverage (`fpa_data_catalog` when the data tools are loaded). Separate supported targets from desired-but-unmeasurable targets.
18
+ 7. Write `planning_brief` using [artifact-contract.md](references/artifact-contract.md).
19
+
20
+ ## Guardrails
21
+
22
+ - A target needs a baseline, direction, threshold/range, and measurement window.
23
+ - Resolve conflicting targets by documenting priority or a trade-off rule.
24
+ - Do not recommend a strategy, simulate results, or approve anything in this phase.
25
+ - If exact period, primary objective, or hard budget boundary is absent and materially changes the decision, return `blocked` with the missing decision.
26
+
27
+ ## Handoff
28
+
29
+ The next skill is `$fpa-diagnose-actuals`. Pass only the frozen `planning_brief`, not an informal summary.
@@ -0,0 +1,41 @@
1
+ # `planning_brief` contract
2
+
3
+ Required fields:
4
+
5
+ ```yaml
6
+ artifact_type: planning_brief
7
+ status: complete | complete_with_limits | blocked
8
+ period:
9
+ id: string
10
+ start_inclusive: timestamp
11
+ end_exclusive: timestamp
12
+ timezone: IANA timezone
13
+ comparison_period: same shape
14
+ reporting_currency: ISO-4217 code
15
+ scope:
16
+ app_ids: []
17
+ stores: []
18
+ channel_groups: []
19
+ decision_question: string
20
+ primary_objective:
21
+ metric: string
22
+ baseline: number | null
23
+ target: number | range
24
+ direction: maximize | minimize | hold | range
25
+ secondary_objectives: []
26
+ controllable_levers: []
27
+ constraints:
28
+ budget_floor: number | null
29
+ budget_ceiling: number | null
30
+ allocation_limits: []
31
+ business_constraints: []
32
+ risk_guardrails: []
33
+ measurement_feasibility:
34
+ supported: []
35
+ unsupported: []
36
+ assumptions: []
37
+ open_decisions: []
38
+ created_at: timestamp
39
+ ```
40
+
41
+ Every unsupported metric must name the grain, field, or maturity gap causing the limitation.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: fpa-recommend-strategy
3
+ description: Select and express an auditable UA strategy recommendation from validated objectives, Actuals, driver evidence, and simulated scenarios. Use after scenario simulation to create a proposal for independent review and human approval.
4
+ ---
5
+
6
+ # FP&A Strategy Recommendation
7
+
8
+ Load `$fpa-apply-core-rules` first. Recommend one plan while keeping alternatives and uncertainty visible.
9
+
10
+ ## Procedure
11
+
12
+ 1. Consume `planning_brief`, `driver_analysis`, and `strategy_scenarios`.
13
+ 2. Remove scenarios that breach hard constraints.
14
+ 3. Rank remaining scenarios using the objective priorities and declared trade-off rule.
15
+ 4. Select one recommendation and specify exact allocation, changes from baseline, expected ranges, assumptions, and risks.
16
+ 5. State why rejected alternatives were not chosen.
17
+ 6. Define next-cycle evaluation thresholds; do not create a real-time monitoring obligation.
18
+ 7. Write `strategy_proposal` using [artifact-contract.md](references/artifact-contract.md).
19
+
20
+ ## Boundaries
21
+
22
+ - Do not add a new scenario whose results were never simulated.
23
+ - Do not hide downside results or convert uncertainty into a single guaranteed number.
24
+ - Do not approve, execute, or call the recommendation an official forecast.
25
+ - If no scenario satisfies hard constraints, return `blocked` or recommend reopening planning assumptions.
26
+
27
+ ## Handoff
28
+
29
+ Send the complete proposal and its cited upstream artifacts to `$fpa-review-strategy`. The recommending agent must not perform that independent review.
@@ -0,0 +1,30 @@
1
+ # `strategy_proposal` contract
2
+
3
+ ```yaml
4
+ artifact_type: strategy_proposal
5
+ status: complete | complete_with_limits | blocked
6
+ strategy_version: string
7
+ planning_brief_id: string
8
+ strategy_scenarios_id: string
9
+ recommended_scenario_id: string
10
+ target_period: {start_inclusive: timestamp, end_exclusive: timestamp, timezone: string}
11
+ allocation:
12
+ - app_id: string
13
+ store: string
14
+ channel_group: string
15
+ spend: number
16
+ change_from_baseline: number
17
+ expected_outcomes:
18
+ downside: {}
19
+ base: {}
20
+ upside: {}
21
+ decision_rationale: []
22
+ rejected_alternatives: []
23
+ material_assumptions: []
24
+ risks: []
25
+ hard_constraints: []
26
+ next_cycle_evaluation_thresholds: []
27
+ required_human_decisions: []
28
+ ```
29
+
30
+ The total allocation must reconcile to the proposed total budget, and every allocation row must map to a simulated scenario row.
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: fpa-review-cycle
3
+ description: Compare newly arrived Actuals with the previously frozen approved forecast, explain variances, evaluate assumptions, and feed learning into the next planning cycle. Use only after the completed business period's data snapshot has arrived and passed diagnosis.
4
+ ---
5
+
6
+ # FP&A Cycle Review
7
+
8
+ Load `$fpa-apply-core-rules` first. This workflow is event-driven by a new period data snapshot, not by continuous monitoring.
9
+
10
+ ## Entry gate
11
+
12
+ Require the immutable `approved_cycle_forecast` and a newly diagnosed `actuals_snapshot` covering the same period and comparable scope. If data is incomplete or source grain is incompatible, narrow the review or return `blocked`.
13
+
14
+ ## Procedure
15
+
16
+ 1. Verify that forecast and Actuals refer to the same period, timezone, currency, App, Store, Channel, and metric window.
17
+ 2. Compare against the frozen forecast; never regenerate it using known outcomes.
18
+ 3. Calculate absolute and percentage variance from additive components: Actuals via `fpa_query`/`fpa_compare`, forecast-vs-actual arithmetic via `fpa_calc`.
19
+ 4. Attribute variance to execution difference, volume, efficiency, conversion, retention/LTV, mix, external factors, model error, and data effects where evidence supports it.
20
+ 5. Score each material assumption as supported, weakened, rejected, or unresolved.
21
+ 6. Capture reusable learning and proposed changes for the next planning brief.
22
+ 7. Write `cycle_review` using [artifact-contract.md](references/artifact-contract.md).
23
+
24
+ ## Boundaries
25
+
26
+ - Do not revise historical forecast values.
27
+ - Do not equate an execution receipt with proof that the strategy caused the outcome.
28
+ - Do not automatically start or approve the next strategy; emit recommended planning inputs only.
29
+
30
+ ## Handoff
31
+
32
+ If another cycle is desired, pass `cycle_review` to `$fpa-plan-cycle` as prior-cycle evidence.
@@ -0,0 +1,30 @@
1
+ # `cycle_review` contract
2
+
3
+ ```yaml
4
+ artifact_type: cycle_review
5
+ status: complete | complete_with_limits | blocked
6
+ forecast_version: string
7
+ actuals_snapshot_id: string
8
+ review_period: {start_inclusive: timestamp, end_exclusive: timestamp, timezone: string}
9
+ comparability_checks: []
10
+ variance_summary:
11
+ - metric: string
12
+ forecast: number | null
13
+ actual: number | null
14
+ variance: number | null
15
+ variance_pct: number | null
16
+ variance_drivers:
17
+ - category: execution | volume | efficiency | conversion | retention_ltv | mix | external | model | data | unknown
18
+ contribution: number | null
19
+ evidence: []
20
+ confidence: high | medium | low
21
+ assumption_evaluation:
22
+ - assumption: string
23
+ outcome: supported | weakened | rejected | unresolved
24
+ evidence: string
25
+ lessons: []
26
+ next_cycle_inputs: []
27
+ unresolved_questions: []
28
+ ```
29
+
30
+ Use `variance = actual - frozen_forecast` and `variance_pct = variance / NULLIF(ABS(frozen_forecast), 0)`. Keep percentage variance `NULL` when the frozen forecast is zero.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: fpa-review-strategy
3
+ description: Independently challenge a proposed UA strategy, its evidence, calculations, assumptions, feasibility, and governance before human approval. Use only with an independently authored strategy proposal; never use to self-approve a recommendation.
4
+ ---
5
+
6
+ # FP&A Independent Strategy Review
7
+
8
+ Load `$fpa-apply-core-rules` first. The reviewer must be independent from the recommendation agent and must receive the full evidence chain.
9
+
10
+ ## Procedure
11
+
12
+ 1. Verify artifact lineage from `planning_brief` through `strategy_proposal`.
13
+ 2. Recalculate material totals and ratios from cited components.
14
+ 3. Test source-grain compatibility, scenario-to-proposal traceability, model support, and uncertainty coverage.
15
+ 4. Challenge hidden assumptions, extrapolation, concentration risk, feasibility, and downside exposure.
16
+ 5. Check that the proposal satisfies hard constraints and contains no implied execution authority.
17
+ 6. Record findings by severity and issue one opinion: `support`, `support_with_conditions`, or `reject`.
18
+ 7. Write `strategy_review` using [artifact-contract.md](references/artifact-contract.md).
19
+
20
+ ## Authority boundary
21
+
22
+ - `support` is a reviewer opinion, not approval.
23
+ - Only an external human approval artifact can authorize the official forecast or execution.
24
+ - Do not rewrite the proposal in place. Required changes create a new strategy version and a new review.
25
+
26
+ ## Handoff
27
+
28
+ If the reviewer supports the proposal, send both artifacts to the human approval gate. After explicit approval, `$fpa-forecast-approved-strategy` may run.
@@ -0,0 +1,25 @@
1
+ # `strategy_review` contract
2
+
3
+ ```yaml
4
+ artifact_type: strategy_review
5
+ status: complete | complete_with_limits | blocked
6
+ reviewed_strategy_version: string
7
+ reviewer_identity: string
8
+ independence_confirmed: boolean
9
+ opinion: support | support_with_conditions | reject
10
+ recalculation_checks:
11
+ - check: string
12
+ result: pass | warn | fail
13
+ evidence: string
14
+ findings:
15
+ - severity: critical | high | medium | low
16
+ category: data | math | model | feasibility | risk | governance
17
+ finding: string
18
+ evidence: string
19
+ required_action: string
20
+ conditions_for_human_approval: []
21
+ residual_risks: []
22
+ reviewed_at: timestamp
23
+ ```
24
+
25
+ Set `independence_confirmed: false` and `status: blocked` if the reviewer also authored the proposal. Any unresolved critical finding requires `reject`.