Skip to main content

PowerFill Module — Phase 5 Architect Kickoff

This is the prompt Kevin pastes into a new Cursor session to bootstrap the Systems Architect on PowerFill Phase 5 (Carry-Cost Calculator).

Important context for this kickoff: Phase 4's first attempt was the catalyst for canonicalizing the v4.1 Deploy Verification Gate and the "Verification Avoidance" antipattern candidate. Phase 5 inherits those lessons — they are baked into the prompt below. Use Opus 4.7 High Thinking (or equivalent reasoning model). Do NOT use Cursor Auto for this phase — Phase 4's auto-mode attempt produced a known-broken commit that required substantial rework.

Usage

  1. Open a new Cursor session in the PSSaaS repo.
  2. Set the model to Opus 4.7 High Thinking (or your project's strongest reasoning model).
  3. Copy everything inside the fenced block below.
  4. Paste as the first message in the new session.
  5. The Architect will self-onboard and respond with an acknowledgement.

The Prompt

You are the PSSaaS Systems Architect agent. This is a new session.

Start with your session-start checklist:

1. Read `CLAUDE.md` (project identity, invariants, role-identification procedure)
2. Read `AGENTS.md` (agent memory: principles, lessons, preferences,
especially the "push is an ask" convention and the F-PSD findings summary)
3. Read `docs-site/docs/agents/architect-context.md` (your role definition,
including v4 Required Delegation Categories)
4. Read `docs-site/docs/agents/process-discipline.md` (canonical v4.1)
5. Read `docs-site/docs/agents/handoff-prompts.md` (templates for delegating)
6. Read `docs-site/docs/handoffs/pssaas-session-handoff.md` (current state)
7. Read `docs-site/docs/agents/powerfill-architect-phase5-kickoff.md`
(this kickoff doc — full task description below)

After you have read those, acknowledge your role and proceed with the
Phase 5 task as described below.

== YOUR TASK — PowerFill Phase 5 ==

**Scope: Carry-Cost Calculator service.**

Phase 4 delivered the configuration management surface for `pfill_carry_cost`
(CRUD APIs, monotonicity-warning validation). Phase 5 builds the
**runtime calculator** that consumes those configured curves to compute
carry cost for loan-trade pairs. The calculator is a Phase 6 prerequisite —
the allocation engine scores candidates by `prx_and_carry` (price plus
carry), so without a working calculator Phase 6 cannot allocate correctly.

Per the spec at `docs-site/docs/specs/powerfill-engine.md` line 419:
"Phase 5: Carry cost calculator + CRUD APIs — 3-5 days." The CRUD half
already shipped in Phase 4; Phase 5 is the calculator half plus any
calculator-specific APIs the Architect surfaces.

== KEY CONTEXT FROM TONIGHT'S POC SESSION (2026-04-16) ==

A real customer database (PS_DemoData) is now live as a tenant accessible
via X-Tenant-Id: ps-demodata. It contains:

* 295 rows of production carry-cost data in pfill_carry_cost
* Sample carry-cost row shape (verified):
investor_instrument_name='15 fhlmc cash 85k', on_day=0, to_day=15, annual_rate=0.270000
investor_instrument_name='15 fhlmc cash 85k', on_day=16, to_day=30, annual_rate=0.270000
investor_instrument_name='15 fhlmc cash 85k', on_day=31, to_day=45, annual_rate=0.270000
* The instrument-name vocabulary includes patterns like '15 fhlmc cash 85k',
'15 fhlmc cash 110k', '10/6mo fnma 4929', '10 umbs', etc.

Phase 5 work should be designed AND validated against PS_DemoData, not just
the local pssaas-db container. Use `X-Tenant-Id: ps-demodata` for all
real-data validation. PS_DemoData is at SQL compatibility level 150 and
kevin_pssaas_dev now has db_ddladmin (Phase 4 confirmed both empirically).

== LEGACY REFERENCE (carry-cost computation in Desktop App) ==

The legacy NVO at `X:\dev\other\PowerSeller-App\plugins\powerfill\n_cst_powerfill.sru`
computes carry cost in `psp_powerfill_conset` via this pattern (search
for `pfill_carry_cost` in the NVO; key lines around 1330-1360):

WITH @average_carry_rate AS (
SELECT loan_id, trade_id, instrument_name,
AVG(pcc03.annual_rate) AS avg_rate,
interest_earning_days
FROM (...working set...)
INNER JOIN dbo.pfill_carry_cost pcc03
ON ...investor_instrument_name AND day-bucket containment...
GROUP BY ...)
SET carry_cost = CAST(acr04.avg_rate * acr04.interest_earning_days
AS NUMERIC(9,6))
SET prx_plus_carry = CAST(price + carry_cost AS NUMERIC(11,8))

The shape: for each (loan, trade) pair, find the matching carry curve row
by (investor_instrument, day-bucket), apply rate to interest-earning-days,
add to base price. Assumption A11 frames this as "days x rate" but flags
the exact day-bucket and interpolation rules as needing Tom/Greg confirmation.
Phase 5 must verify A11 against the actual NVO formula.

== EXPLICIT OUT OF SCOPE ==

* Allocation engine (Phase 6) — psp_powerfill_conset, the allocation
passes that USE the carry-cost calculator
* psp_powerfillUE / synthetic trades subsystem (Phase 6, A28) — see
`docs-site/docs/legacy/powerfill-syn-trades-deep-dive.md`
* React UI (Phase 8)
* PowerBuilder Connector Plugin spec/code (separate workstream)

== PROCESS DISCIPLINE REQUIREMENTS (v4.1 + tonight's lessons) ==

1. **Verification-before-completion is non-negotiable.** Phase 4's first
attempt shipped a known-broken commit because dotnet build/test were
not run before commit. Required pattern in this project:

docker exec pssaas-api dotnet build --nologo
docker exec pssaas-api dotnet test --nologo --no-build

These are documented in AGENTS.md technical-lessons section. If your
shell can't access the container, surface that fact to the Collaborator
BEFORE committing — don't proceed past a failed verification step.

2. **Primary-Source Verification Gate** — both arms:
- Static: read the NVO carry-cost computation directly. Verify A11 against
real SQL. The NVO is the source of truth; the spec and the assumptions
log are derived.
- Live: probe pfill_carry_cost in PS_DemoData. Sample several
investor_instrument_name values. Confirm column types match what the
PowerFillCarryCost entity declares. Tonight's session caught 4
entity-drift findings against PS_DemoData — assume nothing.

3. **Deploy Verification Gate** — Phase 4's hardening pattern (e.g., the
GET /settings/preflight endpoint with a `source` field showing
tenant/defaults/builtin) is the model. If Phase 5 introduces new SQL
artifacts, follow the A32 PRINT-in-guard convention.

4. **Required Delegation Categories** — the calculator is computation-
heavy, not boilerplate-heavy. Delegation candidates are limited:
probably just unit tests if you write enough of them. Document
Deliberate Non-Delegation justification per v4 §8 if you self-implement
work that matches a default-delegate category.

5. **Gate Output Action mandatory disposition per finding** — corrected
in place / scope-changed / deferred-with-justification. Phase 4's F3
escalation is the exemplar for how to handle a finding that requires
PO input.

6. **Push is an ask, not a tell** — never `git push`. Commit only.

== WHAT I WANT FROM YOU ==

1. **Enter Plan mode** (use the SwitchMode tool).
2. **Read carry-cost specifics:**
- Spec §"Carry Cost Configuration" (lines 85-90) — what the spec says
- Assumption A2 (carry cost is a scoring modifier, not a filter)
- Assumption A11 (days x rate; needs Tom/Greg confirmation on exact rules)
- The NVO carry-cost computation (grep for `pfill_carry_cost` in
`n_cst_powerfill.sru`; key lines around 1330-1360)
- PowerFillCarryCost entity to understand current EF mapping
3. **Run the Primary-Source Verification Gate** against:
- Spec claims about carry-cost shape
- PowerFillCarryCost entity vs PS_DemoData column-by-column
- The actual NVO computation vs A11's framing
4. **Probe PS_DemoData**:
- Sample 5-10 carry curves and characterize the data shape
- Confirm whether day-buckets are contiguous, whether they ever overlap,
whether annual_rate ever varies within a single instrument's curve
5. **Produce a CreatePlan output** with these sections (mirror Phase 4
plan structure at `.cursor/plans/powerfill-phase-4.plan.md`):
- §1 Scope (in / out)
- §2 Primary-Source Verification Gate findings + dispositions
- §3 The carry-cost computation (formal algorithm; reference NVO line
ranges; flag any deviations from A11)
- §4 New service (PowerFillCarryCostCalculator or similar) — surface,
inputs, outputs, where it lives, who calls it (currently nobody
in Phase 5; Phase 6 will)
- §5 Edge cases — loan with close_date after settlement_date (negative
days), instrument missing from pfill_carry_cost, day-bucket gap
between rows, etc. Each gets an explicit handling decision.
- §6 Calculator-specific APIs (if any) — e.g., GET /carry-cost/preview
that takes a loan/trade pair and returns the computed carry cost
for diagnostic purposes. Optional; Architect's call.
- §7 Alternatives-First decisions
- §8 Delegation plan (likely small for this phase)
- §9 Test strategy (unit tests against the calculator with synthetic
curves; integration test against PS_DemoData with real curves)
- §10 Risks captured
- §11 Counterfactual Retro placeholder (filled post-implementation)

6. **Surface open questions for PO input** rather than silently resolving:
- Day-bucket lookup semantics: closed interval [on_day, to_day]?
Half-open [on_day, to_day)? What if a loan's days falls in a gap
between rows?
- Interpolation between buckets (none / linear / step)?
- Behavior when loan's days exceeds the highest to_day in the curve
(extrapolate / cap / error)?
- A2 says "scoring modifier, not filter" — confirm Phase 5 calculator
never returns "loan disqualified" verdicts; that's strictly Phase 6's
allocation pass

7. **Before executing the plan,** wait for me (Kevin, PO) to review and
approve. The Collaborator will read the plan first and offer notes,
same protocol as Phase 4.

== COLLABORATION PROTOCOL ==

* PO is Kevin. Collaborator is in a different Cursor session.
* Escalate decisions affecting: spec/ADR text, BestEx module, tenant
provisioning, cross-product integration. Use handoff-prompts.md
Template 3 for escalations.
* Commit when a logical milestone is complete. Never push.

== CONSTRAINTS ==

* `decimal` for all carry-cost arithmetic — never `float` or `double`
(CLAUDE.md invariant #5)
* Tenant isolation absolute (CLAUDE.md invariant #4)
* Schema preservation per ADR-006 — pfill_carry_cost columns are not
changeable
* Phase 4's PoC artifact (is_ready:true) was achieved against PS_DemoData
with 3 sample constraints. Phase 5 success criterion: a calculator
invocation against PS_DemoData with real configured constraints
returns a sensible carry-cost number.

== WHEN YOU'RE DONE PLANNING ==

Respond with your plan via the CreatePlan tool. Include a short summary
and the resolution of each open question above (resolved with rationale,
or escalated with proposed options).

What Happens After

  1. Kevin pastes the prompt into a new Cursor session running Opus 4.7 High Thinking.
  2. Architect acknowledges role, reads onboarding docs.
  3. Architect produces a CreatePlan for Phase 5 calculator.
  4. Architect surfaces open questions (especially day-bucket semantics) to PO via Collaborator.
  5. PO and Collaborator review.
  6. PO approves; Architect dispatches any delegation per §8 and self-implements the calculator.
  7. Architect produces completion report following the Phase 4 v2 report style (gate findings with dispositions, delegation outcomes, counterfactual retro).
  8. Collaborator reviews and commits.

Notes

  • The Phase 4 plan at .cursor/plans/powerfill-phase-4.plan.md (gitignored — local copy on the Architect's machine) is the structural reference. Match its format.
  • Phase 4 had a known-broken first attempt (Cursor Auto agent shipped without verification). Tonight's PoC session demonstrated the verification pattern that prevents it. Follow the verification pattern.
  • The PoC is "live" against PS_DemoData with 3 sample constraints + 1 lockdown configured. Phase 5's calculator can use those configurations as input data for integration testing.