Skip to main content

PSSaaS — Session Handoff

Living document for instruction-fade countermeasure. Updated at alignment checkpoints. Read this FIRST when resuming after context rollover. Checkpoint: 2026-04-20 (Phase 8.5 W1 EMPIRICALLY CLOSED ~14:40 UTC after ~3 hours of runtime-cutover-iteration; 7 sequential runtime failures diagnosed + fixed + verified end-to-end; auth boundary live + embedded SDK rendering Hub dashboard inline; PO browser-flow PO-verified). Sentinel phase-8-5-ecosystem-ready LIVE on staging at https://pssaas.staging.powerseller.com/. Phase 8.5 PO milestone "I can demo PSSaaS to Greg in staging, with Keycloak auth, with embedded Superset dashboards inside the operator UI" empirically achievable.

The 7 runtime-cutover failures (compressed; full sequence in cross-project-relays archive):

#SymptomRoot causeFamily classificationFix commit
1oauth2-proxy CrashLoopBackOff (cookie_secret 44 bytes vs required 16/24/32)PSX Infra delivered openssl rand -base64 32 output literallyMember 3 instance 2 (answerer→asker)live-patch + ad94642
2OIDC callback Missing parameter: code_challenge_methodKeycloak PKCE S256 required without matching client configMember 3 instance 3live-patch + ad94642
3OIDC callback 500 (audience [account] does not match)Keycloak default audience claim doesn't include client itselfMember 3 instance 4live-patch + ad94642
4nginx-ingress 502 (upstream sent too big header)proxy_buffer_size default too small for JWT+9-roles cookieGeneric integration taxlive-patch + ad94642
5React UI 404 on /api/superset/guest-tokenModules.Superset.dll missing from runtime image (Dockerfile.prod COPY-set incomplete)PSSaaS-internal artifact-vs-artifactad94642
6Same 404 post-Dockerfile-fixEndpoint registered at /api/superset/superset/guest-token (double-prefix from nested MapGroup + relative path)PSSaaS-internal artifact-vs-artifact7b9a87c
7503 (dashboard_key 'hub' has no UUID configured)ConfigMap injected flat keys (hub); .NET binding expected PowerFillEmbedUuids__HubPSSaaS-internal artifact-vs-artifactlive-patch + da03740

Member 3 family at 4 instances within ~3 hours, all PSSaaS Architect ↔ PSX Infra agent pair (instance 1 asker→answerer realm-name; instances 2-4 answerer→asker delivered-shape gaps). Per PSX Collab close-out round 3 family-velocity-as-evidence-signal observation: 4-member-within-72-hours triggers proposed canonical revision, BUT existing threshold's "multiple agent pairs" criterion NOT yet met. Member 3 stays "Banked, not yet canonical" pending second-agent-pair instance. Bidirectionality (asker→answerer + answerer→asker) is family-coherence evidence per PSX Collab's count-it-with-asterisk reasoning.

PSX Infra meta-rule earned empirical receipts within hours of being banked. PSX Infra's W1-cross-project-response generalization ("security-hardening config defaults often require symmetric client-side config; flag the symmetry explicitly when delivering, don't ship asymmetric free upgrades") was banked at PSX side BEFORE failures 3 + 4 surfaced. Worth noting because it argues for the value of banking generalizations early at the rule level (PSX's framing) rather than only at the symptom level.

Sub-pattern not yet a Member: PSSaaS-internal artifact-vs-artifact convention drift. Failures 5, 6, 7 share a different shape — same family heading conceptually but the writer + reader are two PSSaaS-internal artifacts rather than two cross-project Collaborators. Worth tracking as candidate distinct sub-family if a third instance surfaces. Banked in cross-project-relays archive § "Phase 8.5 W1 runtime cutover sequence" for future watch.

Strategic data-richness question opened by W1 close: PO's first reaction to the working Hub dashboard was "Seems fairly useless. Where do I see the good stuff?" — empirical fresh-eyes feedback that the architectural-correctness narrative didn't survive contact with the empty-data reality (per A66: PS_DemoData has no syn-trade arbitrage; psp_powerfillUE rebuilds the user-facing tables empty by design intent). Per-report dashboards 14-20 also empty for same reason. Path posture revised 2026-04-20 PO-direction: (a) frame-the-empty-state-well demo DEMOTED to fallback-only ("I won't bug Greg to look at PSSaaS PowerFill until we have data for reports"); (b) sanitized customer data via Joe is the load-bearing path — PO outreach to Joe in flight; demo waits; (c) ELIMINATED — PS608 (Watermark TPO) does not use PowerFill, so it can't surface PowerFill demo data. Chunk-#2 selection conversation with Greg gains added load: Watermark TPO doesn't use PowerFill (chunk #1) so the original "what would you like next?" framing becomes "what does Watermark TPO actually use that we should do next?" — the chunk-#1-was-PowerFill rationale itself is open with PO + worth surfacing in the chunk-#2 framing rethink. A66/A69/A54 technical-implementation consultation routes through Rudy (junior dev currently in the PowerFill code), not Tom. Tom remains canonical authority on Desktop App config patterns + legacy PowerBuilder code archaeology for Phase 10+ cutover-shape conversations. Greg-demo deferred until data lands. Backlog #32 status: WAITING ON JOE.

Three pending follow-ups, none Greg-demo-blocking by themselves:

  1. PSX Infra Audience mapper add (removes the oidc_extra_audiences = ["account"] workaround; quality-upgrade not blocker)
  2. PSX Infra acknowledgment relay (W1-actually-closed framing + the audience-mapper request + meta-rule-earned-receipts framing)
  3. PSX Collab close-out round 4 acknowledgment (Member 3 instance count + meta-rule adoption + family-velocity observation)

Previous Checkpoint (preserved as historical): 2026-04-20 (Phase 8.5 W1 cross-project response RECEIVED + 2 PSSaaS-side fixes APPLIED + 2 banked process observations from the exchange). PSX Infra delivered all 7 asks per 2026-04-20-psx-keycloak-pssaas-app-client-response (PSX commit 64dbec8; PSSaaS-side response file in working tree pending PSSaaS push). What shipped THIS sub-session (post-PSX-response Architect fixes; pending PO push):

  1. REALM-NAME LOAD-BEARING FIXinfra/oauth2-proxy/oauth2-proxy.cfg + infra/azure/k8s/pssaas-staging/services.yaml ConfigMap mirror updated: oidc_issuer_url from https://auth.powerseller.com/realms/pss-platformhttps://auth.powerseller.com/realms/psx-staging. Without this fix oauth2-proxy fails OIDC discovery on first start. Original W1 commit 4c3b921 had the wrong realm name from PSSaaS Architect's unverified inference (K8s namespace name = realm name) — PSX Infra's response empirically confirmed only master, psx-staging, pss-services realms exist; resolved by creating pssaas-app in psx-staging (the cross-project staging realm).
  2. SUPERSET-CREDS SECRET REFERENCE FIXinfra/azure/k8s/pssaas-staging/services.yaml updated to reference the actual delivered Secret name pssaas-superset-credentials (PSX's chosen name; cleaner separation than the original ask of patching pssaas-secrets) with the actual delivered key names (SUPERSET_URL, SUPERSET_ADMIN_USERNAME, SUPERSET_ADMIN_PASSWORD). Switched .NET BaseUrl to use the in-cluster URL http://superset.pss-platform.svc.cluster.local:8088 per PSX's explicit recommendation — avoids TLS/ingress overhead + stays off public internet for the server-to-server 3-step handshake. Public URL https://bi.staging.powerseller.com remains in appsettings.Staging.json as a sensible pre-Secret-applied fallback (env vars win in ASP.NET Core's standard config-builder ordering).
  3. oauth2-proxy-secrets.yaml.example reframed as historical-reference + as-delivered-shape documentation. Live cluster Secret was direct PSX Vault → K8s injection (PSX bundled both client_secret AND cookie_secret in same Secret per their explicitly-flagged-and-justified deviation; accepted PSSaaS-side); template stays for Phase 10+ cloning + DR. appsettings.Staging.json Superset section gets a _comment explaining the env-var override.
  4. Banked observation #1: realm-vs-namespace conflation as a 3rd member of the "Writer-Time vs Reader-Time Truth Divergence" family (existing 2 members: build-shape verification at relay-answer time; state-freshness verification at relay-compose time; new 3rd: infrastructure-name verification at relay-compose time). Also a sub-instance of the "Single-Probe Confidence" banked observation (now 3-instance corroborated: PSX Infra two-databases falsification at Phase 8 W2 + embedded-SDK-OFF claim + this realm-name claim). Threshold tracking: family member (c) currently at 1-instance-from-1-agent-pair; not yet hitting canonical-submission threshold. Banked in 2026-04-20-psx-keycloak-pssaas-app-client-response §"Lessons banked".
  5. Banked observation #2: PSX's response shape (explicit deviation flagging + rationale + reversibility offer) is the inverse-positive of the "Subagent Output Defended Beyond Scope" banked antipattern (W2-PS608 origin). Banked PSSaaS-side as a positive pattern shape worth replicating in our own future cross-project relays + subagent dispatches.

Pending verification recipe (the bilateral cross-boundary cutover per AGENTS.md, ready to run post-PO-push of these fixes + post-PO-kubectl apply -f services.yaml for first-deploy of oauth2-proxy Deployment):

  1. curl -I https://pssaas.staging.powerseller.com/app/ → expect HTTP 302 to Keycloak login page on auth.powerseller.com/realms/psx-staging/...
  2. curl -I https://pssaas.staging.powerseller.com/api/health → expect HTTP 401
  3. curl -I https://pssaas.staging.powerseller.com/docs/ → expect HTTP 200 (UNCHANGED)
  4. Browser login flow end-to-end → expect post-login /app/ 200 with React UI rendering + JWT contains tenant_id: ps-demodata claim (verifiable via Application → Cookies in DevTools)
  5. PSSaaS API /api/superset/guest-token end-to-end (post-register-powerfill-embeds.py run; ConfigMap populated): operator clicks any report → embedded dashboard renders inline

Backlog #31 status update: PSSaaS-side artifact-level GREEN + W1 cross-project collaboration RECEIVED + PSSaaS-side fixes APPLIED. Bilateral cross-boundary cutover verification recipe pending PO-push + PO-kubectl apply + PSX-Infra-brokered registration script run. Greg-demo dry run becomes runnable end-to-end post-recipe-pass.

One PSX-side non-blocking caveat banked: GUEST_TOKEN_JWT_SECRET on Superset uses the hardcoded fallback in superset_config.py rather than a Vault-injected env var. PSX Infra confirmed it's stable + matches what's in Vault; their backlog item to migrate to Vault-injected env. NOT blocking PSSaaS W2-4. Banked here so future Architect re-readers see the asymmetry between Vault-canonical-storage + Superset-runtime-source-of-truth.


Previous Checkpoint: 2026-04-20 (PowerFill Phase 8.5 (Ecosystem Auth + Embedded Superset SDK) COMPLETE pending PO push + PSX Infra collaboration; sentinel phase-8-5-ecosystem-ready (drops the -validation-ready and historical -a54-fixed sub-suffixes; Phase 8.5 is the new authoritative milestone). What shipped THAT session (Phase 8.5 W1 + W2 + W3 + W4 + cross-cutting; W1 already committed atomically as 4c3b921 per Reviewable Chunks; W2-4 + cross-cutting in a16e4a7; pending PO push of both):

  1. W1 (oauth2-proxy + Keycloak realm/client setup) — committed atomically as 4c3b921. infra/oauth2-proxy/oauth2-proxy.cfg + infra/azure/k8s/pssaas-staging/services.yaml (oauth2-proxy ConfigMap + Deployment + Service) + infra/azure/k8s/ingress/pssaas-ingress.yaml (delegates /oauth2/, /app/, /api/ to oauth2-proxy:4180; /docs/ UNCHANGED) + oauth2-proxy-secrets.yaml.example template + .github/workflows/deploy-staging.yaml rolling-restart step + cross-project-relay request to PSX Infra at docs-site/docs/agents/cross-project-relays/2026-04-20-pssaas-keycloak-pssaas-app-client-request.md + W1 checkpoint Architect Report at docs-site/docs/handoffs/powerfill-phase-8-5-w1-checkpoint.md
  2. W2 (Embedded Superset SDK in React UI)@superset-ui/embedded-sdk@^0.3.0 added (lazy-loaded at lib-Cb7LCDYX.js 6.82KB / 2.78KB gzipped chunk); new src/frontend/src/components/EmbeddedDashboard.tsx (PSX SupersetEmbed.tsx-shape; useEffect chain; iframe-sizing containerRef polling; cleanup contract); anchor-link → embedded-component swaps in reportShell.tsx + RunStatus.tsx + Home.tsx (Hub embedded inline as canonical proof-of-life surface per A66 + ADR-027 demo narrative coherence); A66 BLUE banner UX preserved (FreshnessBanner BEFORE embed; embed NOT rendered for TerminalEmpty); A69 status honesty preserved (step.error_message render unchanged); App.tsx Header tenant-picker DISABLED with tooltip + Sign out link added
  3. W3 (.NET 8 guest-token-mint endpoint + registration script) — new src/backend/PowerSeller.SaaS.Modules.Superset/ module per ADR-004 modular-monolith pattern: SupersetGuestTokenClient.cs (typed HttpClient + 3-step Superset handshake login → CSRF → guest_token POST + X-CSRFToken header per "most-missed piece" gotcha + Referer header cousin gotcha + SemaphoreSlim-guarded session cache with 5-min TTL + 401-invalidates-cache); SupersetEndpoints.cs (POST /api/superset/guest-token + 401/400/503/502/200 status taxonomy); SupersetExtensions.AddSupersetModule(IConfiguration) extension (canonical first instance of IHttpClientFactory registration in the codebase per Phase 8.5 plan §2 Consolidation Gate); SupersetOptions + PowerFillEmbedUuids IOptions bindings; appsettings.Staging.json + services.yaml env-from-Secret + configMapRef wiring; placeholder ConfigMap powerfill-embed-uuids-configmap.yaml. infra/superset/register-powerfill-embeds.py DELEGATED to fast subagent per plan §6 — Flask app context primary path (matches deploy-powerfill.py + deploy-dashboards-flask.py); subagent output passed the W2-PS608-antipattern first-question check; no scope drift
  4. W4 (A68 long-term decoupling code shape) — new Tenant sealed record at src/backend/PowerSeller.SaaS.Infrastructure/Data/Tenant.cs; TenantRegistry.Resolve(identity) returns Tenant? tuple; TenantMiddleware resolution-precedence INVERTED (OIDC tenant_id claim from X-Forwarded-Access-Token wins over legacy X-Tenant-Id header per ADR-029); internal ExtractClaimFromAccessToken helper does base64url JWT-payload decode (no signature validation per trust-of-gateway model — oauth2-proxy already validated); InternalsVisibleTo for Api.Tests
  5. ADR-029 (NEW; Accepted) at docs-site/docs/adr/adr-029-pssaas-tenant-identity-strategy.md documents the long-term shape + the v1 code-shape-only PO disposition + the JWT trust-of-gateway model + 4 alternatives + Phase 10+ follow-up checklist
  6. ADR-027 status flipped Proposed → Accepted with full §"Decisions deferred to Phase 8.5 Architect — Architect-at-dispatch resolutions" rewrite documenting each deferred item's actual disposition
  7. A68 PARTIALLY RESOLVED in docs-site/docs/specs/powerfill-assumptions-log.md with the 2026-04-20 status update block at top of entry
  8. Sentinel bumped phase-9-validation-readyphase-8-5-ecosystem-ready in PowerFillModule.cs + SupersetModule.cs
  9. Spec amendment: new Phase 8.5 row in Phased Implementation table at docs-site/docs/specs/powerfill-engine.md
  10. ADR index updated at docs-site/docs/arc42/09-architecture-decisions.md (ADR-027 → Accepted; ADR-029 added)
  11. Completion report at docs-site/docs/handoffs/powerfill-phase-8-5-completion.md (18-row Capability × Environment matrix per practice #13; 4 environment columns; bilateral cross-boundary cutover verification recipe; A66/A69 honesty preservation evidence; 8-observation Counterfactual Retro)
  12. Devlog at docs-site/docs/devlog/2026-04-20-powerfill-phase-8-5.md
  13. Greg-demo-readiness handoff amended with two load-bearing slot-in slides per kickoff

Empirical first-run state: dotnet build PowerSeller.SaaS.sln clean (0 warnings, 0 errors; 11 projects compiled); dotnet test PowerSeller.SaaS.sln clean (250 passed + 6 skipped + 0 failed; was 233 pre-Phase-8.5; +17 net-new: 8 SupersetGuestTokenClient + 9 TenantMiddleware); npm run build clean (272.69KB JS gzipped; SDK lazy-loaded chunk separated); npm run typecheck + npm run lint clean. Pending PSX Infra collaboration: Keycloak pssaas-app client + client_secret + realm-side tenant_id mapper + Superset admin creds + 5-item Superset embedding pre-flight verification (especially PUBLIC_ROLE_LIKE pre-flip per PSX gotcha #1). Bilateral cross-boundary cutover verification recipe pending post-collaboration. Per Capability × Environment matrix practice #13: PSSaaS-side artifact-level GREEN; runtime-level NOT MEASURED HERE.

Phase 8.5 PO milestone — "I can demo PSSaaS to Greg in staging, with Keycloak auth, with embedded Superset dashboards inside the operator UI" — empirically achievable post-bilateral-verification. Phase 8.5 IS the last demo-blocker per PO sequence preference. After PSX Infra collaboration lands + the smoke-test passes, Greg-demo dry run becomes runnable end-to-end against the auth-protected staging URL.

Banked process observations (added to those from prior sessions; not yet canonical):

  • Reviewable Chunks shape can be over-ridden mid-session by PO directive without invalidating the prior chunk artifact (W1 checkpoint report stays authoritative even when execution skips the inter-session pause)
  • Trust-of-gateway model for v1 JWT validation IS a defensible pattern when the gateway is the only path AND the gateway already does signature validation; full JwtBearerHandler is the Phase 10+ replacement
  • Server-side-driven config values (UUIDs from registration script → ConfigMap → endpoint response) avoid client-bundle-rebuild as a coupling point; future server-driven config values should default to this shape
  • internal + InternalsVisibleTo is the canonical .NET pattern when a private helper grows to merit testing (preserve correct visibility scope; tests still get direct access)
  • Pre-push docs-build check now 11-instance corroborated (Phase 8.5 W1 was 10th; this Phase 8.5 wrap is 11th); canonical-promotion-ready-for-Collaborator-nomination
  • Backlog re-read pass at planning time now 6-instance corroborated (Phase 7 / 8 W1 / 8 W2 / 9 / 8.5 W1 / 8.5 W2-4-cross-cutting); canonical-promotion-ready
  • "contract-per-artifact density high → self-implement" + "delegate mechanical idempotent script gen" combined heuristic now 5-instance corroborated across Phase 8 W1 + 8 W2 + 9 + 8.5 W1 + 8.5 W2-4
  • Build-time test-bug findings (RecordingHandler ObjectDisposedException + DefaultHttpContext default-200 + InternalsVisibleTo) ARE caught by Deploy Verification Gate arm (b) when build + test cycle runs immediately after writing production code (~30s per cycle via Docker SDK 8.0 container)

Previous Checkpoint: 2026-04-20 (PowerFill Phase 9 (Parallel Validation Harness) COMPLETE pending PO push; sentinel phase-9-validation-ready (drops the -a54-fixed sub-suffix per kickoff §"Cross-cutting"; A54 closure is now historical). What shipped THAT session (Phase 9; pending PO push):

  1. tools/parallel-validation/ — Python parallel-validation harness (~10 source files, ~1,500 LOC); pyodbc + requests + Jinja2 stack; runs in WSL Ubuntu against local pssaas-api + PS_DemoData public endpoint per Option L runtime
  2. docs-site/docs/devlog/2026-04-20-powerfill-phase-9-first-validation-run.md — first end-to-end harness run output (auto-rendered by the harness); the load-bearing Greg-demo asset addition
  3. docs-site/docs/adr/adr-028-phase-9-parallel-validation-harness-design.md — full ADR documenting Frame D Hybrid framing + 4 architectural decisions (invocation path, language, output format, runtime location); renumbered from initial ADR-027 due to a parallel Collaborator-authored ADR-027 (Superset Embedding Strategy) landing in commit ece500e during the Phase 9 dispatch window
  4. src/backend/PowerSeller.SaaS.Modules.PowerFill/Contracts/ReportContracts.cs — A67 closure (9 XML doc-comment paths re-aligned)
  5. src/backend/PowerSeller.SaaS.Modules.PowerFill/PowerFillModule.cs — sentinel bumped to phase-9-validation-ready
  6. docs-site/docs/specs/powerfill-engine.md Phase 9 row marked DONE; new Phase 10 row for production cutover
  7. docs-site/docs/specs/powerfill-assumptions-log.md — A69 (state-dependent UE failure on non-empty post-pool_guide state on PS_DemoData) + A70 (Frame D framing refinement)
  8. docs-site/docs/handoffs/powerfill-phase-9-completion.md — W2-shaped completion report with full Capability × Environment matrix per practice #13
  9. docs-site/docs/devlog/2026-04-20-powerfill-phase-9.md — devlog entry per template-7

Empirical first-run state: PSSaaS run 9312a638-cd21-4485-b42e-ee8dc02be0d0 Complete in ~30s (allocated_count=515; pool_guide_count=515; post_ue_*=0 per A66 rebuild-empty pattern). Sqlcmd-direct path completed conset (8.5s) + pool_guide (1.3s) but failed at psp_powerfillue with SqlException 207 'Invalid column name note_rate'. UE in isolation against post-PSSaaS-rebuild-empty state runs cleanly (~2.7s). State-dependent UE failure surfaced as A69 — exactly the class of finding Phase 9's harness was built to surface. The harness's verdict logic was hardened post-first-run to honor the asymmetric-failure case via a new RowVerdict.INCOMPARABLE classification (Capability Inflation countermeasure verified empirically). A69 reproduction: 4 consecutive harness runs all surfaced the identical SqlException at the identical EXEC step. A70 banked documenting the related architectural framing refinement (PS_DemoData has mixed PSSaaS-deployed + legacy-encrypted proc-body state; only psp_powerfill_pool_guide is plain text per A50 + A54 fix).

Phase 9's PO milestone — "I have empirical loan-by-loan evidence that PSSaaS PowerFill matches the legacy Desktop App on PS_DemoData" — is empirically achievable in the more honest Frame D Hybrid form (orchestration-equivalence on PS_DemoData with explicit "NOT MEASURABLE HERE" cells for the customer-DB question), pending A69 root-cause resolution and customer-rep approval for the operator-driven sweep.

Next phase choice (PO call): (a) A69 root-cause investigation + customer-DB sweep planning, OR (b) Phase 8.5 (ecosystem auth + Superset embedding per Backlog #30/#31).

PO disposition 2026-04-20 (post-Phase-9-ship): Chose (b) Phase 8.5 dispatch. Rationale: Phase 8.5 is the only remaining demo-blocker (PO milestone explicitly requires Keycloak auth + staging URL); A69 root-cause is a demo asset in current banked form, not a demo blocker; sequence-execution per the prior A54-fix → W2 → Phase 9 → Phase 8.5 → Greg-demo plan; sooner-friction-discovery for Phase 8.5 is preferred (more recovery time before Greg). Phase 8.5 kickoff at docs-site/docs/agents/powerfill-phase-8-5-kickoff.md ready for Architect dispatch.

Backlog #30 closed empirically clean (PSX Infra completed Superset → pss-platform migration ~3 min cutover with hostname unchanged + dashboards preserved + same Keycloak SSO + same image SHA so existing GUEST_TOKEN_JWT_SECRET continuity preserved; Phase 8.5 inherits a stable platform-Superset endpoint with no migration coordination needed). AKS shared-cluster pod-density resolved (PSX Infra added 3rd node aks-userpool1-16401317-vmss000000 separate node pool 2026-04-20; sentinel phase-9-validation-ready LIVE on staging post-resolution). PSX Collab embedding-pattern relay COMPLETE (authoritative file paths + Q3 architectural-mismatch correction (oauth2-proxy + static-site, NOT NextAuth + Next.js) + 8 ranked gotchas + "what I am NOT providing" honesty list; archived + ADR-027 (Proposed) drafted with all 5 D-8.5 framing decisions inheriting from PSX file paths). PSX Collab close-out adopted "Writer-Time vs Reader-Time Truth Divergence" family heading for the 2 banked observations from the exchange (build-shape verification + state-freshness verification, threshold-tracking explicit, each at 1-instance-from-1-agent-pair).

Banked process observations (added to those from prior sessions; not yet canonical):

  • Backlog re-read pass at planning time IS now 4-instance corroborated (3 traditional findings + 1 "0 findings = pattern works" data point this session); canonical-promotion proposal banked for Collaborator nomination
  • The "contract-per-artifact density high → self-implement" heuristic is now 2-instance corroborated (Phase 8 W2 + Phase 9 both shipped 0 subagents)
  • Reviewable Chunks at sub-checkpoint scope (3 Andon pulls this session, all producing material PO decisions) IS the right granularity for empirical-discovery sessions; banking for canonical-revision consideration
  • Practice #13 Environment-Explicit Inventory is now baked INTO the harness deliverable itself (not just into completion reports); the comparison_report.md.j2 template's Capability × Environment matrix block is a load-bearing structural element
  • Phase 9 deliverables should be evaluated by what FINDINGS they SURFACE, not by their "all green" rate (the harness earned its Phase 9 charter on its very first run by surfacing A69)

Previous Checkpoint: 2026-04-20 (Phase 8 fully COMPLETE + DEPLOYED + post-deploy verification done + Phase 9 kickoff drafted + Phase 8.5 (NEW) scoped + Backlog #30 platform-Superset migration banked; sentinel phase-8-superset-react-ready-a54-fixed was live on staging). What shipped that session (8 commits, all pushed):

  1. 4b08b51 + f4531ae — W2 kickoff prep (post-A54-fix + canonical-family inherited context refresh)
  2. 10f9891 + 9be1b8e + 1de964d — W2 ship (Architect): React UI under src/frontend/, K8s + GHA deploy pipeline, ADR-026, A67, completion report
  3. Post-W2-deploy Collaborator-side verification + fixes:
    • d4d294e — F-W2-PSD-1 fix (PS608 removed from tenant dropdown — out-of-scope addition by Architect; tenant ID renamed to lowercase-hyphenated ps-demodata to match backend convention; case-insensitive TenantRegistry for hygiene)
    • 8dba7b4 — Path γ for F-W2-PSD-1 fallout (Tenants__ps-demodata__ConnectionString env var added to staging API Deployment so request-time tenant ID matches existing pfill_run_history row tags; A68 banked documenting the long-term tenant-id-vs-config-slot decoupling concern as Phase-8.5-natural-fold)
    • 9a83b92 — Backlog #30 (Superset → pss-platform migration; PSX-Infra-driven per PO direction) + #31 (Phase 8.5 NEW — PSSaaS joins ecosystem auth via Keycloak + replaces W2's "View in Superset" anchor links with embedded Superset SDK; queued behind #30 + PSX Collab response on their embedding pattern); A64 + A68 platform-tailwind notes

Empirical staging state: API sentinel phase-8-superset-react-ready-a54-fixed; /app/ HTTP 200 with <title>PowerFill — PSSaaS Operator</title>; /app/healthz 200; GET /runs with X-Tenant-Id: ps-demodata returns 12 historical rows (3 Complete + 7 Failed + 2 Cancelled) — the post-A54-fix run-history is now visible end-to-end through the operator UI.

PO milestone test (PowerFill reports with drill-down in Superset that I can review) is empirically achievable. PO has done the dry-run click-through against staging. One product-instinct upgrade surfaced: PO wants embedded Superset (not new-tab "View in Superset" anchor links) AND Keycloak auth on /app/ for the Greg demo. Both rolled into Phase 8.5; depends on Backlog #30 (Superset → pss-platform migration, PSX-Infra-driven) + a PSX Collab relay asking how they wired their oauth2-proxy + Keycloak + embedded-SDK pattern.

Next phase: Phase 9 kickoff at docs-site/docs/agents/powerfill-phase-9-kickoff.md (drafted this session; ready to dispatch in parallel with Phase 8.5 — surfaces don't overlap). Phase 9 ships the Parallel Validation Harness against PS_DemoData per the PSSaaS migration thesis ("chunk-by-chunk extraction, with each chunk verifiably matching legacy behavior loan-by-loan"); first comparison run output formatted to slot into powerfill-a54-fix-greg-demo-readiness.md "Bug as Feature" demo as the "loan-by-loan parity proof" addition.

Banked process observations (not yet canonical, accumulating for next discipline-doc revision):

  • Subagent Output Defended Beyond Scope (W2 origin: PS608 tenant dropdown — Collaborator initially defended as "naming-convention decision" rather than recognizing as scope drift; PO had to push back; surfaced empirical refinement to Required Delegation Categories — review subagent output with first-question "is this what the kickoff asked for?")
  • Convention conflation under low-corroboration count (A68 root pattern: single-writer PoCs feel coherent because there's only one convention, breaking moment a second writer arrives; refinement to practice #13 — matrix cells should probe convention-coherence ACROSS cells, not just per-cell verification)
  • Single-Probe Confidence (PSX Infra falsification of "two databases" hypothesis + the "embedded-SDK off" claim that I couldn't actually verify without authenticated PSX access — pattern: probe one artifact at one boundary, get plausible signal, reason forward instead of asking "do I have enough evidence?"; countermeasure: when claim crosses ownership boundary [infra vs application; cross-product; auth-gated surface], require either second independent probe or explicit owner-confirmation before treating finding as load-bearing).

Phase 8 fully complete. Phase 9 kickoff ready to dispatch. Phase 8.5 queued behind Backlog #30 + PSX Collab response.


Platform Identity

PowerSeller SaaS (PSSaaS) — Cloud-native replacement for the PowerSeller Desktop App. Manages secondary marketing operations: pipeline tracking, BestEx pricing, trading, pooling, risk/hedging, settlement. Sits alongside PSX (PowerSeller X) which handles loan marketplace execution.

Stack: .NET 8 / C# (modular monolith API), React + TypeScript (frontend, not yet built), Azure SQL MI (database-per-tenant), Docker Compose with Nginx proxy.

Namespace: PowerSeller.SaaS.*

Local access: http://pssaas.powerseller.local/docs/ (Docusaurus), http://pssaas.powerseller.local/api/ (.NET API)

Repo: github.com/KevinSawyer/powerseller-saas (private)


Platform State

Infrastructure — Local Docker + Staging (ADR-020)

Staging (pssaas-staging on AKS, ADR-020):

  • Target URL: https://pssaas.staging.powerseller.com/ (docs at /docs/, API at /api/, Swagger at /api/swagger/)
  • Namespace: pssaas-staging on shared pss-cluster (alongside psx-staging and pss-platform)
  • Images: GHCR at ghcr.io/kevinsawyer/powerseller-saas/{docs,api}
  • CI/CD: GitHub Actions — path-filtered builds, kubectl set image deploy
  • Database: SQL MI (PS_DemoData) via secret-injected connection string
  • Auth: None yet (ADR-013 Proposed). Internal staff only.
  • Status: LIVE. Docs, API, Swagger, Redis all running. TLS provisioned. Superset connection registered but blocked on SQL MI firewall (AKS outbound IP needs whitelisting).

Local Docker (unchanged):

  • Nginx reverse proxy on 127.0.0.1:80 (pssaas.powerseller.local)
  • Hosts file: Add an explicit entry for pssaas.powerseller.local (NRPT routes *.powerseller.local to the dev server, so local Docker needs a hosts override to hit 127.0.0.1).
  • Docusaurus pinned to 3.6.3 with webpack 5.97.1 override; full-text search plugin removed (incompatible — re-add when a compatible plugin version exists). 42+ documents.
  • .NET 8 API with 21 BestEx endpoints + health + Swagger
  • SQL Server 2022 container with seeded schema (20 core tables)
  • Redis cache container
  • Azure SQL MI connection verified (PS608 / Watermark TPO, read-only user kevin_pssaas_dev)
  • PS_DemoData sandbox database on Azure SQL MI — complete sanitized dataset from an old PowerSeller client. Read/write access via kevin_pssaas_dev. Same host/port as PS608. Contains: 11,674 active loans, 116,014 loan history, 20,208 shipped loans, 53,002 bid loans, 8,902 trades, 6,246 pools, 14,495 prices, 10,138 risk analysis loans, 1,826 BestEx results. This is the test/validation dataset for all PSSaaS development.
  • Docker Compose profiles: default (proxy + docs), dev (+ api, db, cache), frontend (web, no code yet), full (+ identity, bus, mail)

.NET Solution Structure

src/backend/PowerSeller.SaaS.sln
PowerSeller.SaaS.Api/ → Host (Minimal APIs, Swagger, tenant middleware)
PowerSeller.SaaS.SharedKernel/ → Abstractions (ITenantContext, IModule, Result)
PowerSeller.SaaS.SharedDomain/ → Shared entities (Loan, Instrument, ProfileInstrumentMapping, TodaysPrice)
PowerSeller.SaaS.Infrastructure/ → EF Core, multi-tenancy (TenantDbContext, TenantRegistry)
PowerSeller.SaaS.Modules.BestEx/ → BestEx engine (19 entities, 6 services, 21 endpoints)
PowerSeller.SaaS.Modules.PowerFill/ → PowerFill (23 pfill tables [17 Phase 1 + 1 Phase 4 preflight settings + 4 Phase 6d syn-trades/log + 1 Phase 6e run history] + 10 upstream [+1 Phase 7 PscatTradeCashGrid per A61] + 2 views + 6 procs + constraints rowversion; preflight + preprocess + configuration + carry-cost calculator + run orchestrator + run history + cancel registry + run queue + background worker + startup reconciliation + report (Phase 7) services; preflight/preprocess/settings/constraints/carry-cost/lockdown/run [202 async]/runs list/runs detail/runs cancel/candidates preview/8 Phase 7 report endpoints; sentinel `phase-7-reports-ready`)
tests/
PowerSeller.SaaS.Modules.BestEx.Tests/ → 32 passing tests
PowerSeller.SaaS.Modules.PowerFill.Tests/ → 200 tests passing (194 unit + 6 SQL/InMemory-blocked Skipped; 4 of the 6 are PFILL_TEST_SQLSERVER-env-gated SQL integration tests, 2 are InMemory-blocked Phase 6a placeholders). Phase 6e added 48 net-new; **Phase 7 added 27 net-new** (7 freshness + 10 happy-path + 5 pagination + 3 edge + 2 tenant-scoping = 27).
PowerSeller.SaaS.Api.Tests/

BestEx Engine — Implemented

  • 24-step analysis pipeline (12 fully implemented, 8 simplified with TODOs)
  • 19 domain entities mapping to existing SQL MI schema
  • 6 services: ProfileService, AnalysisPipelineService, PricingCalculator, FeatureAdjustmentService, RankingService, AnalysisRunService
  • 21 Minimal API endpoints (profiles CRUD, analysis run/results/errors, loans)
  • 32 unit tests (PricingCalculator formulas)
  • Spec: Approved

Superset Dashboards — Designed

  • 15 SQL query files in infra/superset/queries/ — 6 report translations + 5 BestEx charts + 4 Position Recon charts
  • Dashboard design doc at docs-site/docs/superset/dashboard-designs.md — layouts, cross-filtering, KPIs
  • Setup guide at docs-site/docs/superset/setup-guide.md — connection config for PSX infra team
  • LIVE at PSX Superset: https://bi.staging.powerseller.com
  • Data source: PS_DemoData (354 BestEx loans, 11K pos recon rows, 5M archive rows)
  • SEC 105/109 tables empty in DemoData — queries ready for when data exists

Desktop App Plugin — Written

  • desktop-plugin/psxllpa/ — 10 PowerBuilder source files, README, and API_REFERENCE.md (HTTP contract for Tom).
  • Calls PSX's ephemeral LLPA evaluation endpoint (ADR-099 implemented in PSX).
  • PSX also has ADR-098 (agency LLPA ingestion) implemented — stacks with buyer_id = "FNMA"/"FHLMC".
  • For Tom to import into PowerBuilder IDE and compile.
  • Not yet tested — Tom needs an API key from PSX ops and staging access before end-to-end testing.

Key ADRs (23)

PSSaaS ADR count: 26.

ADRTitleStatus
001Backend — .NET 8 / C#Accepted
002Frontend — React + TypeScriptAccepted
003Cloud — Azure-Preferred, Vendor-AgnosticAccepted
004Architecture — Modular Monolith FirstAccepted
005Database — SQL MI, Database-Per-TenantAccepted
006Schema — Preserve InitiallyAccepted
007Audience — New Customers FirstAccepted
008UX — Two Modes (Modern + Power)Accepted
009Docs — DocusaurusAccepted
010Documentation — Arc42 + ADRs + SpecsAccepted
011Ecosystem Product BoundariesAccepted
012Odoo as Commercial LayerAccepted
013Identity StrategyProposed
014Backend Language Divergence (.NET vs Python)Accepted
015Desktop App CoexistenceAccepted
016Nginx Proxy + Docker Compose ProfilesAccepted
017Ecosystem Hostnames (*.powerseller.local)Accepted
018Local SQL Server for DevelopmentAccepted
019PSX-to-SaaS BestEx IntegrationProposed
020Shared Kubernetes Cluster with PSXProposed
021PowerFill Port Strategy (hybrid T-SQL + C#) — Amended 2026-04-19 with §Narrow Bug-Fix Carve-Out (A54 = canonical first instance)Proposed (amended)
022PowerFill Allocation Algorithm (port iterative passes)Proposed
023PowerFill Constraint Model (preserve legacy tree)Proposed
024PowerFill Async Run Pattern (BackgroundService + Channel)Proposed
025PowerFill Report API Pattern (Phase 7 latest-Complete-wins)Proposed
026Frontend Framework + Build Pipeline (Phase 8 W2 Vite + React + TS + Tailwind)Proposed

Specs

SpecStatusPriority
BestEx EngineApproved, ImplementedTier 1 — done
Pipeline ManagementDraftImmediate — WTPO's near-term need
PSX BestEx IntegrationDraftFuture — when WTPO adds agency delivery
Risk Validation ModuleNot written yetNext spec — discussed; validate Desktop App LLPA integration when written
PowerFill EngineDraft (Phase 0–5 + 6a/6b/6c/6d/6e COMPLETE; Phase 7 + 8 W1 + 8 W2 COMPLETE; A54 fix shipped 2026-04-19)Full module port planned in 10 phases; ADRs 021-026 drafted (ADR-021 amended 2026-04-19 with §Narrow Bug-Fix Carve-Out; ADR-026 NEW 2026-04-19 documents Phase 8 W2 frontend framework + build-pipeline choice). A54 + A56 RESOLVED 2026-04-19 via two surgical fixes inside psp_powerfill_pool_guide (PK extension + pt13 JOIN qualifier extension) within ADR-021 carve-out scope. End-to-end Complete PowerFill run achievable against PS_DemoData (run 43e8f148-..., 30s wall-clock); sentinel phase-8-superset-react-ready-a54-fixed (post-W2). A65 NEW (multi-pa_key + settlement-date variance are two distinct latent triggers; Phase 9 probe needed). A66 NEW (UE clears + rebuilds-empty user-facing tables on syn-trade-empty datasets like PS_DemoData; documented expected behavior; Phase 9 / Greg-consultation followup; load-bearing for W2 BLUE-vs-YELLOW banner UX distinction). A67 NEW (ReportContracts.cs XML doc paths show stale /reports/<name> segment that doesn't match actual RunEndpoints.cs route registrations; cosmetic Phase 9 deferral). 233/233 tests pass (32 BestEx + 200 PowerFill + 1 Api + 6 skipped) — unchanged through W2 (no test pinned the sentinel string). Phase 8 fully complete; Phase 9 (Parallel Validation Harness) is the next phase.

Ecosystem Context (Critical — Do Not Forget)

Products

  • PowerSeller Desktop App — Legacy PB 22.0. 5 licensed modules: Data Manager, Secondary Manager, Risk Manager, Post-Closing Manager, AppRunner Manager. Tom maintains. Still in active use.
  • PowerSeller X (PSX) — Loan execution platform. Python/FastAPI. Two modules: Xarbi (arbitrage, CRA/non-QM/jumbo) and Xigo (direct agency delivery, future). 99+ ADRs. Production staging at psx.staging.powerseller.com.
  • PSSaaS — This project. Cloud-native Desktop App replacement.
  • PowerSeller MBS Access — Odoo v18, B2B subscriptions for dataQollab MBS market data.

Watermark TPO (MWFI Holdings) — Anchor Customer

  • First PSX principal (Xarbi — CRA loan arbitrage)
  • First PSSaaS tenant (when ready)
  • Only customer on Azure SQL MI (PS608 database)
  • Uses OptimalBlue for rate sheet generation (PSX Xigo will replace)
  • NOT yet doing agency delivery (future)
  • Buying loans from sellers: First Home, US Mortgage, Kind Lending, Lenderworks, Loan Steady
  • CRA eligibility via e11tec/Incenter integration
  • WTPO loan ID format: 2350YYMMDDNNN
  • LOS: Encompass (PSSaaS will push purchased loans to it)

Key People

PersonRoleRelevance
Kevin SawyerCTO, 40% owner, Product OwnerMakes all decisions
LisaCEO, 60% owner, MWFI CEODomain authority, strategic direction
GregContract President, prior ownerHedging/risk knowledge (time-limited)
JayOps ManagerPower user, customer advocate, secondary marketing experience
TomSenior DevPowerBuilder veteran, ~5 years to retirement, maintains Desktop App
RudyJunior DevMigrating source control, eager for SaaS, 10-15 year horizon
JoeIT / InfrastructureAzure, Docker, security, customer migration

Strategic Discoveries (This Session)

  1. WTPO's immediate need is NOT BestEx — it's CRA spread arbitrage on PSX. BestEx is for future agency delivery.

  2. Pipeline Management is the real near-term PSSaaS need — post-purchase tracking that the Desktop App handles via BidMgr plugin.

  3. PSSaaS Pipeline is a secondary marketing overlay, not a loan system of record. The LOS (Encompass) is the SoR. PSSaaS manages buyer selection, profit spread, delivery timing, settlement.

  4. The Desktop App's Data Manager is the foundational module but its ETL (1,600+ SQL conversion rules) is painful. PSX replaces this.

  5. BidMgr and bid_pkg are different modules — BidMgr is inbound (seller tapes), bid_pkg is outbound (investor bid packages).

  6. dataQollab already provides TBA pricing via api.mbsmkt.com — no new vendor needed for Xigo.

  7. Agency LLPAs are public Excel files — PSX ingests them (ADR-098), evaluates them via stacking engine with buyer_id = "FNMA"/"FHLMC".

  8. Loan table baseline: 143 standard columns + ~12 custom per customer. WTPO has 14 custom columns.

  9. Rate sheet generation needed NOW for Xarbi (not just future Xigo) — reference buyer price minus margin.

  10. WTPO's generated rate sheet is stored as an extracted_profile in PSX with participant_type = 'principal'.

  11. BidMgr vs bid_pkg — BidMgr is inbound (seller tapes); bid_pkg is outbound (investor bid packages). 42,732 bid confirmations at WTPO show BidMgr is actively used.

  12. dataQollab (api.mbsmkt.com) already provides TBA pricing data — no new vendor needed for Xigo; PowerSeller is licensed to use it.

  13. WTPO needs rate sheet generation now for Xarbi (reference buyer price minus margin), not only for future Xigo.

  14. WTPO's generated rate sheet in PSX: stored as extracted_profile with participant_type = 'principal' and buyer_id = "watermark-tpo".

  15. PSX solution architect: Xarbi and Xigo share the stacking engine — agency LLPAs use the same grid model with buyer_id = "FNMA"/"FHLMC".

  16. SpecialFeatureCode (e.g. HomeReady SFC 900) is not available at Risk Manager stage — assigned at commitment/delivery time. Desktop App exposes feature_code_001006 on pools/instruments, not on loans.

  17. Desktop App licensing — five modules by name: Data Manager, Secondary Manager, Risk Manager, Post-Closing Manager, AppRunner Manager.

  18. Website content — drafts written for all four product modules plus overview; pending review by Lisa, Greg, and Jay.

  19. MIAC SRP workbook is a market pricing grid, NOT loan-level valuations. Structure: base SRP by rate spread + adjustments for FICO/UPB/LTV/program/remit/term. Structurally identical to LLPA grids — evaluable by PSX stacking engine. Client-specific calibration, tenant-level data.

  20. MIAC SRP grids use a universal template with client-specific calibration. Compared Third Federal (8 sheets, 1 servicing tier, no state adjustments) vs. LG (9 sheets, 3 servicing tiers, full 50-state adjustments). Adjustment grids (FICO/UPB/LTV) are nearly identical across clients. A single parser handles all clients.

  21. Rudy (junior dev) wants the same pattern as Tom's LLPA integration: send loan data to an API, get SRP evaluation results back. 9 required fields (all already in rmcat_loan / loan tables), 4 optional. Endpoint location (PSX vs PSSaaS) pending PO decision. The Desktop App still needs SQL/stored procedures to wire SRP results into BestEx and Risk Manager — the API only computes; it does not integrate.

  22. PS_DemoData sandbox database loaded to Azure SQL MI — complete real-world dataset (sanitized old client) with read/write access. Enables BestEx validation against historical results, Risk module testing, value discovery analysis, and end-to-end pipeline testing. Connection: same host/port as PS608, database name PS_DemoData.

  23. Superset dashboards designed from Desktop App reports.

  24. pssaas-staging infrastructure ready for deployment. ADR-020 accepted the shared AKS cluster model. Production Dockerfiles (multi-stage nginx for docs, multi-stage aspnet for API), K8s manifests, ingress rules, CI/CD workflows, and an 8-step infra agent handoff are written. Pending: PSX infra agent applies manifests, creates DNS, builds first images.

  25. PowerFill module Phase 0 complete (2026-04-16). Legacy reverse-engineering deep dive, full spec, three ADRs (021 port strategy, 022 algorithm, 023 constraint model), and assumptions log drafted. Tom/Greg unavailable for upfront consultation — source code IS the spec. Every interpretation flagged in assumptions log for future critique. 10-phase roadmap. Engine is ~19K lines of T-SQL; port strategy is hybrid (T-SQL engine in tenant DB + C# orchestration). Algorithm is a verbatim port of the iterative passes; constraint model preserves the legacy tree. Full parity target, modernization deferred.

  26. Multi-agent structure adopted (2026-04-16). Three PSSaaS agent roles established: Collaborator (Kevin's partner, default), Systems Architect (specs/ADRs/design), Developer (implementation). Role identification required at session start per CLAUDE.md. Role context docs at docs-site/docs/agents/*-context.md. Handoff templates at docs-site/docs/agents/handoff-prompts.md. Triggering event: PowerFill Phase 0 consumed 10K+ lines of markdown in a single session, with 12-16 weeks of implementation work ahead. Specialization unblocks parallel work and reduces context pressure.

  27. Process Discipline canonical adopted ecosystem-wide (2026-04-16). Continuous-improvement framework with Andon-cord principle: any agent can stop the line. PSSaaS hosts the canonical at docs-site/docs/agents/process-discipline.md; PSX and MBS Access reference it. Evolved through v4.1 in one day via cross-project nomination: v1 (6 practices, 8 antipatterns), v2 (PSX Collaborator: Silent Parallel Code Paths + Evidence-Free Diagnosis), v3 (PSSaaS Architect: Phase-0 Truth Rot + Primary-Source Verification Gate), v3.1 (gate scope includes live systems), v4 (PSSaaS Collaborator: Delegation Skip + Required Delegation Categories), v4.1 (PSSaaS Architect: Gate Output Under-Weighting + mandatory disposition). 10 practices, 13 antipatterns, shared nomination template, signal-based cadence. Current revision: v4.1.

  28. PowerFill module Phase 1 complete (2026-04-16). PowerSeller.SaaS.Modules.PowerFill .NET project scaffolded with 17 EF Core entities mapping to the 17 legacy pfill_* tables (Phase 0's stated count of 13 was wrong — direct DDL extraction from n_cst_powerfill.sru line 6004 revealed 17 tables and one misnamed table, pfill_epci_params not pfill_ect_params). Idempotent schema deployment SQL at src/backend/PowerSeller.SaaS.Modules.PowerFill/Sql/001_CreatePowerFillSchema.sql. Integration test SchemaScriptIntegrationTests verified round-trip entity↔schema compatibility against the Docker pssaas-db SQL Server container. Accepted CHAR→NVARCHAR and DATETIME→datetime2 drift for Phase 1 (Assumption A26); Phase 9 will harden via explicit [Column(TypeName)] if parallel validation shows issues. 42/42 tests passing (32 BestEx + 9 PowerFill + 1 Api). The miscount discovery triggered antipattern nomination Phase-0 Truth Rot (approved; added to canonical v3).

  29. PowerFill module Phase 2 complete (2026-04-16). Data access layer + preflight service + both legacy views. Three new Phase-0 Truth Rot findings caught by the new Primary-Source Verification Gate: (a) pfillv_pf_forensics_tradeside view was missing from Phase 0 docs — NVO creates two views, not one; (b) Phase 0 cited pscat_securities_sec_rules which doesn't exist — NVO uses pscat_securitization_rules; (c) pssaas-db was missing 8 tables Phase 2 reads (addressed by extending infra/sql/init/seed-schema.sql). All three corrected in-place. Shared entity extraction (Choice A3): new PowerSeller.SaaS.SharedDomain project holds Loan, Instrument, ProfileInstrumentMapping, TodaysPrice — consolidates what would have been duplicate paths between BestEx and PowerFill; BestEx tests pass unchanged. Preflight surface: 9 composable checks orchestrated by PowerFillPreflightService, exposed at POST /api/powerfill/preflight. Views: both transcribed from NVO into Sql/002_CreatePowerFillViews.sql, deployed via docker-compose.yml mount + setup.sh per-module loop, queried via EF keyless read-models. 60/60 tests pass (32 BestEx + 27 PowerFill + 1 Api). Preflight default thresholds (min_status = "Closed", max_prices_age_days = 2, max_trade_settle_days = 60) await Kevin/Jay/Greg calibration; Phase 4 makes them tenant-configurable. Live-DB discovery prompted gate-scope clarification v3.1.

  30. PowerFill module Phase 3 complete (2026-04-16). Three pre-processing procedures ported from NVO into Sql/003_CreatePowerFillProcedures.sql (261 lines, idempotent DROP-IF-EXISTS + CREATE, WITH ENCRYPTION preserved): psp_add_to_pool_lockdown_guide, psp_pfill_ect_params, psp_pfill_trade_params. C# orchestration: PowerFillPreprocessService invokes the 3 in w_powerfill.srw::ue_perform_preprocess order, stops on first failure, reports per-step status; no explicit transaction (matches Desktop App; all 3 procs are self-idempotent). Exposed at POST /api/powerfill/preprocess. Four Phase-0 Truth Rot findings corrected with explicit Gate Output Action disposition format (first use of v4.1): F1 — procedure named psp_pfill_ect_params even though table is pfill_epci_params (kickoff mis-propagated Phase 1's table-rename to the proc name) — corrected in place; F2 — Desktop App Pre-Process event invokes 3 procs, not 5; the 2 BX procs run in Run event and move to Phase 6 — scope-changed; F3 — pscat_trade_cash_grid missing from pssaas-db; F4 — pscat_pools and pscat_trades_pools_relation missing columns the procs reference — both corrected in place via seed-schema extension. First use of the v4 Required Delegation Categories practice: C2 (SQL transcription) dispatched to a fast subagent; Truth-Rot trap avoidance explicit in the prompt; subagent delivered in one cycle with 0 occurrences of the wrong proc name. Antipattern Gate Output Under-Weighting nominated and accepted to canonical v4.1. 66/66 tests pass (32 BestEx + 33 PowerFill [30 unit + 3 integration] + 1 Api). PS_DemoData deployment of 003 pending kevin_pssaas_dev credentials (Backlog #25).

  31. PS_DemoData live-system probing — five new findings (2026-04-16). Collaborator attempted to deploy 001/003 to PS_DemoData using kevin_pssaas_dev. Discovered: (A28) 3 pfill_syn_* synthetic-trades tables missing from spec — they live outside of_update_database and are populated by procedures the deep dive didn't cover; Phase 6 prerequisite. (A29) CHAR(N) declared in 001 actually exists as VARCHAR(N) in PS_DemoData — confirms A26 in opposite direction; trailing-space semantics differ. (A30) kevin_pssaas_dev lacks DDL perms (db_datareader + db_datawriter only); cannot CREATE PROCEDURE/TABLE/VIEW; PS_DemoData deployments blocked. (A31) pfill_carry_cost already has 295 production rows in PS_DemoData; 001's IF OBJECT_ID IS NULL guards correctly preserve them. (A32) An idempotent DDL script can "succeed" without running any DDL001 returned exit code 0 because all 17 expected tables already exist; if any had been missing, the same Msg 262: CREATE PROCEDURE permission denied would have fired. Refines the Deploy Verification Gate's arm (c): post-state matching expectations is necessary but insufficient; verification must also confirm DDL actually executed (e.g., PRINT inside each IF OBJECT_ID IS NULL guard). All 5 findings logged in PowerFill assumptions log A28-A32 with explicit Gate Output Action dispositions (4 deferred-with-justification, 1 corrected-in-place). Phase 4 explicitly scoped to local pssaas-db container; PS_DemoData deployment is a separate workstream.

  32. PowerFill module Phase 4 complete (2026-04-16; commit 1f2caea initial + follow-up fix: for verification gap). SQL 004_CreatePowerFillPreflightSettings.sql + 005_AddPfillConstraintsRowversion.sql (PRINT per A32). EF + services + ConfigurationEndpoints for preflight settings, constraints (composite routes, ROWVERSION 412, reprioritize collection token 412), sec-rule rel, carry-cost upsert, lockdown (POST create-only 201/409; PUT 404 if missing). PowerFillPreflightService merges pfill_preflight_settings before checks; falls back to built-in defaults if 004 not deployed. GET /settings/preflight always returns a value with a source field (tenant/defaults/builtin). lock_pool normalized to 'y'/'n' on create/update/bulk. F3: spec line 83 "lockdown" delete rule not schema-joinable — interim 409 when pfill_constraint_sec_rule_rel rows exist; documented in assumptions A33, spec, and powerfill-phase4-f3-architect-escalation. Race-condition between DeleteConstraintAsync and AddSecRuleAsync acknowledged in code XML doc + A33 (Phase 6 to serialize). Verification: 87/87 tests pass (32 BestEx + 1 Api + 54 PowerFill including 4 SQL integration via pssaas-db); dotnet build clean (0 warnings). Existing dev DBs created before Phase 4 do NOT block usage — preflight degrades to built-ins — but should still get 004/005 applied for tenant-configurable behavior. Process discipline regression caught and fixed: the initial Phase 4 commit shipped without running dotnet build/dotnet test because dotnet wasn't on the agent shell PATH; the follow-up fix: commit ran the build inside the pssaas-api container, found 4 real failures (rowversion nullability, key-modification on Reload(), seed-schema path inside container) and resolved them.

  33. PowerFill Sub-Phase 6c complete (2026-04-19, pending PO push). Verbatim port of psp_powerfill_pool_guide (live NVO 8770-11185, ~2,415 lines) + psp_pfill_insert4_pool_guide (NVO 11713-12480, ~768 lines) into 009_CreatePoolGuideProcedure.sql (3,274 lines; subagent transcription clean first-attempt). PowerFillRunService extended with Step 5 (pool_guide); RunSummary gains pool_guide_count; sentinel bumped to phase-6c-pool-actions-ready. A38 RESOLVED: psp_pfill_insert4_pool_guide is invoked from inside psp_powerfill_pool_guide body at NVO 11130 (empirical NVO trace; both procs deploy together in 009). 3 new assumptions: A52 (pool_guide forward dep on UE-populated pfill_syn_powerfill_guide — pre-UE snapshot framing), A53 (BR-3 spec drift: legacy emits 9 pool_action values vs spec's 5; spec amended), A54 — Phase 9 carry-over (PS_DemoData snapshot triggers latent legacy ##cte_posting_set_1300 PK violation on multi-pa_key loan/trade pairs; verbatim port preserves; pool_guide_count = 0 on this snapshot until A54 is addressed). 150/6/0 tests pass (was 147/6/0; +3 net-new). Both procs deploy cleanly to local pssaas-db AND PS_DemoData. PoC partial success: Steps 1-4 produce same 515 allocations as 6b; Step 5 reaches pool_guide proc and EXECs for ~31s before A54 surfaces. Sub-phase calendar time ~1 Architect-session (vs breakdown's 5-7 days; subagent dispatch + reusable 6b infrastructure compress velocity). Three-layer Primary-Source Verification Gate produced 11 findings; third corroborating session for the candidate process refinement ("Reference docs are not primary source — even Architect-authored sub-phase plans must be Gate inputs"); ready for v3.1 nomination drafting.

  34. PowerFill Sub-Phase 6e complete + Phase 6 COMPLETE (2026-04-19, pending PO push). Async runtime + audit + concurrency + canonical Phase 6 completion sentinel. Ships 012_CreatePfillRunHistoryTable.sql (pfill_run_history 14-col audit table + filtered unique index ux_pfill_run_history_tenant_active for BR-8 + cursor pagination index per Q1/Q2/Q3/Q7 PO-confirmed defaults), PowerFillRunHistory EF entity (PowerFill table count 22→23), PowerFillRunBackgroundService (BackgroundService + Channel<RunJob> per Q1 Option A — ADR-024), PowerFillRunCancelRegistry (singleton CTS dictionary), PowerFillRunHistoryService (audit CRUD + BR-9 cleanup of 7 user-facing tables / preserve 4 syn-trades + log per A58 + BR-8 SqlException 2627 translation), PowerFillRunStartupReconciliationService (per-tenant sweep marking abandoned active rows as Failed at app startup so BR-8 doesn't permanently block tenants after pod restart), IRunProgressSink callback for status transitions, RunStatus extended 2→7 values with active-set encoded BOTH in SQL filter predicate AND PowerFillRunHistoryService.ActiveStatuses (contract tests pin both byte-for-byte). POST /run returns 202 Accepted + RunSubmissionResponse + Location header (with 409 on BR-8 / 503 on queue saturation / 400 on invalid options); 3 new endpoints: GET /runs (paginated cursor list), GET /runs/{run_id} (full RunResponse from response_json snapshot), POST /runs/{run_id}/cancel. Sentinel bumped to phase-6e-async-runs-ready (canonical Phase 6 completion sentinel). 48 net-new tests (10 cancel registry + 6 queue + 8 RunStatus contract + 14 history service + 1 entity-config + various lifecycle assertions); 206/206 tests pass (32 BestEx + 173 PowerFill + 1 Api + 6 skipped). ADR-024 documents BackgroundService + Channel decision. Spec amendments: §Run Execution Model (full async lifecycle), §Audit Trail (14-col schema), BR-8 (filtered index mechanism), BR-9 (cleanup scope split), §Run APIs (202 + new endpoints), new §"Phase 6e PSSaaS-explicit tables". A58 NEW (BR-9 cleanup scope split — preserves syn-trades + log for forensics per 6d D9 design intent). A56 carry-over update (orchestration layer fully validated against predicted A56 outcome on PS_DemoData; Steps 1-4 baseline 515-allocation preserved; Step 5 hits identical A54 SqlException 2627 at (36177868, 3385000026); BR-9 cleanup verified post-PoC; BR-8 enforced via 409 with active_run_id; cancel signal propagates through linked CTS to SqlClient). A57 second-session corroboration (kickoff specificity → 0 net-new Truth Rot for second consecutive sub-phase; v3.1 nomination drafting well-supported). Sub-phase calendar time ~1 Architect-session (consistent with 6a-6d pattern; well under breakdown's 5-7 day estimate). Phase 6 (Core Allocation Engine) is COMPLETE. Phase 7 (Reports / recap query APIs) now available; Phases 8-10 follow per spec. A54 + A56 remain Phase 9 carry-overs.

  35. PowerFill A54 fix complete (2026-04-19 evening, pending PO push). Mid-stream targeted fix between Phase 8 W1 and W2/Phase 9. Closes the long-deferred A54 PRIMARY KEY violation in psp_powerfill_pool_guide (009_CreatePoolGuideProcedure.sql) so PSSaaS can demonstrate end-to-end Complete PowerFill runs against PS_DemoData. Two surgical fixes inside the legacy proc body, both within ADR-021's amended new §Narrow Bug-Fix Carve-Out (precedent-setting; 4 acceptance criteria; A54 = canonical first instance). Sentinel bumped to phase-8-superset-ready-a54-fixed (suffix-style preserves Phase 8 W1 progress while surfacing the fix from /api/powerfill/status). Empirical-resolution arc: kickoff Option A (PK extension only) shipped first; PoC failed identically (revealing the kickoff's multi-pa_key hypothesis was wrong); Diagnostic-First Rule mid-run probe of pfill_powerfill_guide revealed trade 36177868 had 4 rows with 3 distinct settlement_dates across loans → actual fan-out source was the pt13 INNER JOIN qualifying on trade_id only despite the inline subquery selecting (trade_id, settlement_date); second surgical fix (1-line JOIN qualifier extension) added; PoC then completed end-to-end. Final: run 43e8f148-3d1f-4c40-9f76-a43f84efdfb9 Status=Complete in 30s wall-clock with pool_guide_count: 515, Step 6 (ue) succeeded, 12 events in pfill_powerfill_log. Reproducible (run 7c9dfe50-... 31s). A54 + A56 RESOLVED; A65 NEW (multi-pa_key Switching + settlement-date variance are two distinct latent triggers; both fire on PS_DemoData; PS608 customer DB behavior unknown — Phase 9 probe needed); A66 NEW (UE clears + rebuilds-empty user-facing tables on syn-trade-empty datasets — documented expected behavior, not a bug; A58's "preservation across BR-9" framing carries a sub-clarification — preserved across post-Failed BR-9, but UE's normal end-to-end run rebuilds them per its own logic; Phase 9 / Greg-consultation followup). Post-fix dashboard row counts: Hub 5→11 (latest Complete; new canonical proof-of-life), Cash Trade Slotting 688→0 (UE supersedes Step 4's pfill_cash_market_map per A66 sub-finding), all per-report dashboards 14-19 unchanged at 0 (A66). 233/233 tests pass (Phase 7/8 W1 baseline preserved exactly). Process discipline observations banked for next revision: (a) Backlog re-read pass at planning time now 2-session corroborated (F-8-BR-1 + F-A54-6); (b) Diagnostic-First Rule for carve-out fix sizing — empirical fan-out-source verification belongs in carve-out planning gates; (c) Alternatives-First Gate option-space framing should include diagnosis hypotheses, not just fix shape options; (d) suffix-style sentinel bumps for runtime-block remediation fixes preserve phase tracking AND surface the fix; (e) demo-as-consultation per ADR-021 §Narrow Bug-Fix Carve-Out clause (d) IS viable when the immediate downstream consumer of the fix is the would-be-consulted domain authority; (f) Reviewable Chunks at sub-checkpoint boundaries (3 ANDON-cord pulls this session) IS the right granularity for empirical-discovery sessions. Sub-phase calendar time ~1 Architect-session at ~2x complexity (2 fixes + 4 assumption-log entries + ADR amendment + new Greg-demo-readiness completion report + devlog + session-handoff bump). Greg-demo-readiness completion report at powerfill-a54-fix-greg-demo-readiness with copy-paste-ready "Bug as Feature" demo narrative for the PO.

  36. Phase 9 SHIPPED + AKS pod-density resolved + Phase 8.5 kickoff drafted + 2 cross-project-relay exchanges closed durably (2026-04-20). Multi-deliverable session: (a) Phase 9 (Parallel Validation Harness) shipped by Architect (commits b0f6469 + b548e78 + b350126); harness at tools/parallel-validation/ (Python 3.10 / pyodbc / requests / PyYAML / Jinja2; ~50 source files; 7-case diff-engine self-test PASS; 12-substring renderer self-test PASS); first end-to-end run surfaced A69 (state-dependent psp_powerfillUE SqlException 207 on PS_DemoData; deterministic across 4 runs; UE in isolation vs post-PSSaaS-rebuild-empty state runs cleanly; hypothesis-pair worth Greg/Tom consultation); A70 banked alongside (mixed PSSaaS-deployed + legacy-encrypted proc-body state; only psp_powerfill_pool_guide is plain text); ADR-028 documents Frame D Hybrid framing + invocation-path decisions (renumbered from initial Architect-side ADR-027 collision when Collaborator-authored ADR-027 (Superset Embedding) landed in ece500e during Architect dispatch window); A67 closed (ReportContracts.cs XML doc-paths swept from /runs/{run_id}/reports/<name>/runs/{run_id}/<name> to match RunEndpoints.cs; comment-doc-only edit); sentinel bumped phase-8-superset-react-ready-a54-fixedphase-9-validation-ready (correctly dropped the A54 sub-suffix per Phase 9 kickoff guidance — A54 closure is historical, not gating); Phase 9 completion report + first-run report + devlog + spec amendment + session-handoff bump all per the kickoff. The harness earned its Phase 9 charter on its very first run by surfacing A69 — exactly the class of finding the kickoff predicted. (b) AKS shared-cluster pod-density issue surfaced + resolved: kubectl rollout restart deployment/api post-Architect-push timed out with 0/2 nodes are available: 2 Too many pods; not a PSSaaS bug — shared-cluster capacity hit (PSSaaS + PSX + pss-platform on 2 nodes); PSX Infra resolved by adding 3rd node aks-userpool1-16401317-vmss000000 (separate node pool); pending API pod scheduled + rolled naturally; sentinel phase-9-validation-ready LIVE on staging post-resolution. Cross-boundary cutover verification recipe (per AGENTS.md) applied to confirm no auth regression: /app/ HTTP 200, /docs/ HTTP 200, /api/health HTTP 200, all unauthenticated as designed for current state. (c) Cross-project-relay exchanges closed durably: PSX Infra Superset → pss-platform migration acknowledged + psx-staging namespace references swept from infra/superset/deploy-dashboards-flask.py + AGENTS.md + docs-site/docs/superset/powerfill-dashboards.md (commit f920668); A64 platform-tailwind note marked RESOLVED (commit 9a83b92). PSX Collab Superset-embedding pattern reply received + banked: ADR-027 (Proposed) drafted with all 5 D-8.5 framing decisions inheriting from PSX file paths + 7 ranked Risks from PSX gotchas + Architect-at-dispatch checklist; cross-project-relays archive entry 2026-04-19-psx-superset-embedding-relay.md mirrors the Claim-vs-Evidence family archive shape (commit ece500e); PSX Collab close-out adopted the "Writer-Time vs Reader-Time Truth Divergence" family heading for the 2 banked observations from the exchange (build-shape verification at relay-answer time + state-freshness verification at relay-compose time); each member at 1-instance-from-1-agent-pair, threshold-tracking explicit (commit 31b5d59). (d) Phase 8.5 kickoff drafted at docs-site/docs/agents/powerfill-phase-8-5-kickoff.md (this commit); 4 workstreams (oauth2-proxy + Keycloak; embedded SDK in React; .NET guest-token-mint + registration script; A68 long-term decoupling); ready for dispatch as the LAST demo-blocker before Greg-demo readiness; ADR-027 (Proposed) is the load-bearing inheritance. (e) Banked process observations (not yet canonical, accumulating for next discipline-doc revision): "Subagent Output Defended Beyond Scope" (W2 PS608 origin); "Convention Conflation Under Low-Corroboration Count" (A68 root pattern); "Single-Probe Confidence" (multi-instance origin; first in-flight self-correction observed in this session — PowerShell-bash variable-eating during Phase 9 staging-verify; near-miss caught by second probe); "Writer-Time vs Reader-Time Truth Divergence" family heading (build-shape verification + state-freshness verification, 2 members; threshold tracking). Phase 8 fully complete; Phase 9 fully complete; Phase 8.5 ready-to-dispatch as Greg-demo final-blocker.

  37. Post-W2-deploy verification + F-W2-PSD-1 fix + Path γ + Phase 9 kickoff drafted + Phase 8.5 (NEW) scoped + Backlog #30/#31 banked (2026-04-20). After PO push of W2 (10f9891 + 9be1b8e + 1de964d), Collaborator-side verification surfaced a sequence of post-deploy findings handled in one focused session: (a) Bootstrap: applied infra/azure/k8s/pssaas-staging/services.yaml + pssaas-ingress.yaml to live cluster (frontend Deployment + Service created; ingress reconfigured with /app path; pod healthy in 20s); empirically smoke-tested staging — sentinel API returns phase-8-superset-react-ready-a54-fixed, /app/ HTTP 200 with <title>PowerFill — PSSaaS Operator</title>, asset paths correctly prefixed /app/assets/..., /docs/ + /api/health regression checks 200 (no collateral damage). (b) F-W2-PSD-1 finding: React UI's tenant dropdown sent PS_DemoData PascalCase + included a PS608 (Watermark TPO live customer DB) choice that was scope drift from the W2 kickoff (Architect inferred from broader project context, wrote a doc-comment claiming the kickoff said so; attribution was wrong); backend TenantRegistry is case-sensitive Dictionary lookup — every UI request 401'd Unknown tenant. (c) Fix d4d294e: removed PS608 from dropdown (security: unauth staging URL must not point at live customer DB); renamed tenant ID to lowercase-hyphenated ps-demodata to match backend convention; added StringComparer.OrdinalIgnoreCase on TenantRegistry for hygiene; rewrote tenantConstants.ts doc-comment with the truth (not the attribution). (d) Joint debug with PSX Infra: post-fix staging still returned 0 rows — initial hypothesis "two PS_DemoData databases" (public-endpoint vs private-endpoint discrepancy) was empirically falsified by PSX Infra's primary-source check (az sql mi show confirmed same MI; @@SERVERNAME check confirmed same engine; private-endpoint reaches the populated 11,674-loan PS_DemoData by Azure design). Root cause was application-side: pfill_run_history rows tagged tenant_id='ps-demodata' (Architect's local-route convention) vs staging querying WHERE tenant_id='default' (staging's only configured slot). (e) Path γ 8dba7b4: added Tenants__ps-demodata__ConnectionString env var to staging API Deployment (referencing same existing secret value via 3rd reference; no new secret needed); applied via kubectl apply -f services.yaml; rolled cleanly; staging API now returns 12 historical runs (3 Complete + 7 Failed + 2 Cancelled) under X-Tenant-Id: ps-demodata. A68 banked documenting the long-term tenant-id-vs-config-slot conflation as a Phase-8.5-natural-fold (with Keycloak as source of truth for authenticated user identity, the OIDC tenant_id claim becomes the natural anchor for TenantId-on-rows, decoupled from connection-string-slot routing). (f) PO direction surfaced TWO product-instinct upgrades for Greg demo: (1) embedded Superset (not new-tab "View in Superset" anchor links); (2) Keycloak auth on /app/. Both rolled into NEW Phase 8.5 (PSSaaS joins ecosystem auth + embedded Superset SDK; queued behind PSX Collab response on their embedding pattern). (g) PO architectural call: Superset to migrate from psx-stagingpss-platform namespace (stateless shared resource, co-tenant with Keycloak); PSX Infra-driven; PSSaaS is downstream consumer (re-register dashboards 13-20 + update src/frontend/src/config/supersetDashboards.ts base URL atomically when migration completes). (h) 9a83b92 commits: Backlog #30 (Superset → pss-platform migration) + #31 (Phase 8.5 — ecosystem auth + embedding); A64 amended with platform-Superset multi-tenant-registration tailwind note; A68 amended with Phase-8.5-natural-fold note. (i) Phase 9 kickoff drafted at docs-site/docs/agents/powerfill-phase-9-kickoff.md — ready to dispatch in parallel with Phase 8.5 (surfaces don't overlap); ships Parallel Validation Harness comparing PSSaaS vs Desktop App equivalent on PS_DemoData; first comparison run output formatted to slot into powerfill-a54-fix-greg-demo-readiness.md "Bug as Feature" demo as the "loan-by-loan parity proof" addition; recommends harness invocation Option A (direct sqlcmd against legacy procs, skipping PowerBuilder front-end) to be defended in NEW ADR-027. (j) Banked process observations (not yet canonical, accumulating for next discipline-doc revision): "Subagent Output Defended Beyond Scope" (PS608 dropdown was scope drift; Collaborator initially defended as naming-convention decision; PO had to push back); "convention conflation under low-corroboration count" (A68 root pattern); "Single-Probe Confidence" (PSX Infra falsification of two-databases hypothesis + the embedded-SDK-OFF claim that I couldn't actually verify without authenticated PSX access — pattern: probe one artifact at one boundary, get plausible signal, reason forward instead of asking "do I have enough evidence?"). PO milestone click-through is empirically unblocked; staging surface is operator-ready; Phase 9 is the next phase to dispatch.

  38. PowerFill Phase 8 Workstream 2 (React UI) complete (2026-04-19, pending PO push). Greenfield React operator UI shipping the run-management workflow on top of the Phase 7 + 6e + 8-W1 contracts. src/frontend/ scaffolded via Vite 8 + React 19 + TypeScript 6 + Tailwind v4 + React Router 7 + Prettier (~50 source files; npm run typecheck clean; npm run lint clean 0/0; npm run build clean — 270KB gzipped JS / 17KB gzipped CSS / 0.54KB HTML). 4 main pages (Home / Submit / Runs List / Run Status with polling + cancel + AGENTS.md async-leak countermeasure via useEffect AbortController cleanup) + 8 Phase 7 report pages with shared <ReportPageShell> + 4-verdict freshness banner (per A60 + A66 — Current / Stale / TerminalEmpty Failed-or-Cancelled YELLOW / TerminalEmpty Complete + syn-trade-empty BLUE / RunNotFound 404; the BLUE-vs-YELLOW A66 distinction is load-bearing per kickoff §"Inherited context"); "View in Superset" deep-links to W1 dashboard IDs 13-20 on every report page. New src/frontend/Dockerfile.prod (multi-stage node:22-alpine build → nginx:alpine serve at /app/; mirrors docs-site/Dockerfile.prod); new frontend Deployment + ClusterIP Service in infra/azure/k8s/pssaas-staging/services.yaml; ingress path /app added (per F-W2-BR-3 — /docs/ + /api/ already taken; /app/ chosen for the operator workspace); GHA deploy-staging.yaml extended with frontend path-filter + build-frontend job + idempotent rollout step (with first-deploy kubectl get deployment/frontend guard). Sentinel bumped from phase-8-superset-ready-a54-fixed to phase-8-superset-react-ready-a54-fixed (suffix-style preserves the A54-fix sub-suffix per the cf8ef8b canonical pattern; 1-line change in PowerFillModule.cs). ADR-026 documents framework + build-pipeline choice (Vite + React + TS chosen over Next.js / CRA per Alternatives-First Gate). A67 documents F-W2-CONTRACT-1 (ReportContracts.cs XML doc-comments document /reports/<name> paths that don't exist in routes; actual RunEndpoints.cs registrations use /runs/{runId}/<name> directly; cosmetic XML-doc fix deferred to Phase 9; W2 codes against actual routes per Empirical-Citation Type Mismatch countermeasure). Backlog re-read pass at planning time now 3-instance corroborated (F-7-7 anticipated → F-8-BR-1 caught at planning → F-W2-BR-3 + F-W2-CONTRACT-1 caught at planning) — canonical-adoption proposal banked in W2 completion report for next process-discipline revision. Practice #13 Environment-Explicit Inventory actively applied — Capability × Environment matrix in W2 completion report distinguishes verified-at-artifact-level (this session) vs verified-at-runtime-level (post-push staging click-through, deferred to Collaborator). 0 subagents dispatched — Deliberate Non-Delegation per practice #9 (architectural-contract-per-artifact cost — especially the freshness banner's load-bearing A66 distinction — exceeded artifact-write cost; complements the W1 "delegate the SQL queries" pattern because W1's SQL artifacts had a thinner contract-per-artifact). 233/233 .NET tests pass unchanged (sentinel bump touches no test). Sub-phase calendar time ~1 Architect-session (consistent with 6a-6e + Phase 7 + Phase 8 W1 velocity). Phase 8 fully complete (W1 + A54 fix + W2 all shipped). Completion report at powerfill-phase-8-w2-completion. Phase 9 (Parallel Validation) is the next phase.

  39. PowerFill Phase 8 Workstream 1 complete (2026-04-19, pending PO push). Superset Dashboards. Ships 8 SQL queries (infra/superset/queries/37_*.sql through 44_*.sql) + 1 deploy script (infra/superset/deploy-powerfill.py, 354 LOC, mirrors deploy-loan-pnl.py pattern) + 1 dashboard-design doc (docs-site/docs/superset/powerfill-dashboards.md) + sentinel bump to phase-8-superset-ready. 8 dashboards × 25 charts deployed to PSX Superset (bi.staging.powerseller.com/superset/dashboard/13/ through /20/) against PS_DemoData; column sync succeeded for every dataset; all 8 dataset row counts verified end-to-end through Superset's own engine (5 / 0 / 0 / 0 / 0 / 0 / 0 / 688 — F-7-8 / 688-row Cash Trade Slotting pattern reproduced byte-for-byte from Phase 7's PoC). Architectural decisions: D-8-1 single new deploy script (1-script-per-domain pattern; matches deploy-loan-pnl.py); D-8-2 hybrid 1-hub + 7-detail dashboard structure (matches Phase 7 run_id mental model + Desktop App "one report per screen" mental model); D-8-3 PS_DemoData-only single-DB v1 (per A64 — multi-tenant Superset registration is Phase 9+); D-8-5 Existing Disposition query bypasses encrypted PS_DemoData view per F-8-BR-1 / A63 (defensive query mirrors 002_CreatePowerFillViews.sql CTEs minus note_rate; Phase 7 service catches SqlException 207 but Superset cannot); D-8-6 no outer ORDER BY in any of the 8 SQL files (caught by Deploy Verification Gate arm c — Superset wraps virtual datasets in subqueries; SQL Server Msg 1033). 233/233 tests pass (unchanged Phase 7 baseline; W1 ships zero backend changes beyond one-line sentinel bump). 2 new assumption-log entries (A63 — defensive Existing-Disposition query; A64 — single-DB v1; multi-tenant Phase 9+). First empirical demonstration of Phase 7 CR #1 candidate practice "Backlog re-read pass at planning time": F-8-BR-1 was caught at planning time (Backlog row #24) before any subagent dispatch, before any PoC. Banking for canonical-promotion review at next process-discipline revision (sub-practice of Three-layer Primary-Source Verification Gate's Implementation-vs-runtime layer; F-7-7 + F-8-BR-1 are empirical evidence). Workstream 2 (React UI) deferred to a follow-up Architect session per Reviewable Chunks (PO-confirmed at planning checkpoint; W2 kickoff drafted at docs-site/docs/agents/powerfill-phase-8-workstream-2-kickoff.md). PO milestone "PowerFill reports with drill-down in Superset that I can review" is empirically achievable today. Sub-phase calendar time ~1 Architect-session (consistent with 6a-6e + Phase 7 velocity; 2 subagent batches + Architect-authored docs + ~1 hour of PoC verification through Superset's engine). A54 + A56 + A62 remain Phase 9 carry-overs; Phase 8 W1 dashboards correctly render the carry-over state (6 user-facing dashboards empty; Hub explains why; Cash Trade Slotting renders real data via A58 preservation).

  40. PowerFill Sub-Phase 6d complete (2026-04-19, pending PO push). Verbatim port of psp_powerfillUE (NVO 13246-19801 = _a 13246-16463 + _b 16465-19801; ~6,556 SQL data lines; largest single SQL transcription delegation in the project — 4th iteration of clean first-attempt subagent pattern after 670/5,837/3,274 lines) into 011_CreatePowerFillUeProcedure.sql (6,613 total lines). 4 new tables (3 pfill_syn_* + pfill_powerfill_log) into 010_CreatePowerFillSynTradesSchema.sql; 4 new EF entities (pfill_syn_powerfill_guide_all_rank registered keyless per F-6d-8 empirical PK probe). PowerFillRunService extended with Step 6 (ue) (6 params mirroring conset; 10-min timeout; best-effort post-failure counter hoist); RunSummary gains 6 new fields (syn_trade_base_count, syn_powerfill_guide_all_rank_count, syn_powerfill_guide_count, pfill_powerfill_log_count, post_ue_allocated_count, post_ue_pool_guide_count). Sentinel bumped to phase-6d-ue-syn-trades-ready; 8 net-new RunService unit tests + 1 extended (StepNames lock now 6-step) + 4 EntityConfigurationTests extensions (keyless registry + 4 new table names + composite/single-col key assertions). 158/6/0 tests pass (was 150/6/0; +8 net-new). A28 + A37 RESOLVED (the 4 new tables now PSSaaS-explicit; PowerFill-owned table count: 17 → 22). Both 010 + 011 deploy cleanly to PS_DemoData; 010 clean on local pssaas-db, 011 fails A49 family on local for 6 missing base-schema columns (documented expected per 008's local behavior). PoC against PS_DemoData: Steps 1-4 produce same 515-allocation baseline as 6b/6c; Step 5 (pool_guide) hits A54 at IDENTICAL line/loan/trade as 6c; Step 6 (ue) NOT recorded per fail-fast contract — A56 (NEW) Phase-9 carry-over: doubly-blocked since UE itself re-invokes pool_guide internally at NVO 19795 and would hit the same PK violation. 6d port is structurally correct (4 new tables + UE proc OBJECT_IDs verifiable on PS_DemoData; sentinel + tests green); runtime exercise blocked by A54. Per Option C disposition (PO-confirmed at planning checkpoint). A57 (NEW) banked observation: kickoff specificity at NVO-line-citation level reduces Truth Rot probability — 6d's kickoff was first Phase 6 sub-phase with 0 net-new Truth Rot findings against the kickoff itself. Sub-phase calendar time ~1 Architect-session (vs breakdown's 7-10 day estimate; aggressive subagent + 2-subagent parallel dispatch + reusable 6c infrastructure compress velocity). Three-layer Primary-Source Verification Gate produced 8 findings.

  41. PowerFill Phase 9 (Parallel Validation Harness) complete (2026-04-20, pending PO push). Ships the harness as the empirical lever for the PSSaaS migration thesis ("chunk-by-chunk extraction, with each chunk verifiably matching legacy behavior loan-by-loan against real customer data"). Frame D Hybrid framing PO-confirmed pre-plan via Andon-cord exchange — first comparison run on PS_DemoData proves orchestration parity (PSSaaS API path vs direct sqlcmd path against the SAME proc body set), with explicit "NOT MEASURABLE HERE" cells in the Capability × Environment matrix for legacy-vs-fixed-body parity (per ADR-021's forward-only carve-out — the legacy unmodified body deterministically Fails on PS_DemoData) + the Customer DB column (operator-driven post-Phase-9 sweep). Ships tools/parallel-validation/ (~10 Python source files including harness.py + snapshot.py + pssaas_invoker.py + sqlcmd_invoker.py + diff_engine.py + report_renderer.py + Jinja2 template + harness_config.yaml + requirements.txt + README + install_venv.sh + .env gitignored + check_db.py + 3 diagnose_a69*.py scripts), docs-site/docs/devlog/2026-04-20-powerfill-phase-9-first-validation-run.md (auto-rendered first comparison run output — the load-bearing Greg-demo asset addition), ADR-027 (full architectural decisions: D-9-0 Frame D Hybrid + D-9-1 Option A direct sqlcmd + D-9-2 Python in WSL + D-9-3 Markdown output + D-9-4 Option L local-only + D-9-5 A69 honesty + D-9-6 carry-over scope), A67 closure (9 XML doc-comment paths re-aligned in ReportContracts.cs), sentinel bumped to phase-9-validation-ready (drops the -a54-fixed sub-suffix per kickoff §"Cross-cutting"; A54 closure is now historical). First end-to-end comparison run surfaced A69 (state-dependent UE failure on non-empty post-pool_guide state on PS_DemoData; 4 consecutive harness runs surfaced the identical SqlException 207 'Invalid column name note_rate' at the identical EXEC step; UE in isolation against post-PSSaaS-rebuild-empty state runs cleanly in ~2.7s — state-dependence empirically confirmed) — exactly the class of finding the Phase 9 harness was built to surface; banked for Greg/Tom consultation. A70 banked (PS_DemoData has mixed PSSaaS-deployed + legacy-encrypted proc-body state; production-cutover playbook needs explicit disposition). Verdict logic hardened post-first-run: added RowVerdict.INCOMPARABLE + suppressed A66 Match classification when EITHER side Failed (Capability Inflation countermeasure verified empirically); diff engine self-test gained Case 7 (asymmetric-Failed regression). 7/7 diff engine self-test cases PASS; 12/12 renderer self-test substring matches PASS. 3 Andon-cord checkpoints exercised (Frame D pre-plan; Q1 Q2 carry-over scope; A69 fix_and_continue post-first-run); all 3 produced material PO decisions improving the deliverable. 0 subagents dispatched — Deliberate Non-Delegation per practice #9 (architectural-contract-per-artifact density high; mirrors Phase 8 W2 pattern; now 2-instance corroborated). Sub-phase calendar time ~1 Architect-session (consistent with 6a-6e + 7 + 8 W1 + 8 W2 + A54-fix velocity at ~1.5x complexity). Phase 9 PO milestone empirically achievable in honest Frame D Hybrid form pending A69 root-cause + customer-rep approval for the operator-driven sweep. Banked process observations: (a) Backlog re-read pass at planning time NOW 4-instance corroborated (3 traditional + 1 "0 findings = pattern works" data point); canonical-promotion proposal banked for Collaborator nomination; (b) Practice #13 Environment-Explicit Inventory now baked INTO the harness deliverable itself (not just into completion reports — the comparison_report.md.j2 template's matrix block is a load-bearing structural element of every future harness run); (c) Phase 9 deliverables should be evaluated by what FINDINGS they SURFACE, not by their "all green" rate (the harness earned its Phase 9 charter on its very first run by surfacing A69); (d) Reviewable Chunks at sub-checkpoint scope (3 Andon pulls this session) IS the right granularity for empirical-discovery sessions; (e) The "contract-per-artifact density high → self-implement" heuristic is now 2-instance corroborated. Completion report at powerfill-phase-9-completion. Next phase choice (PO call): (a) A69 root-cause investigation + customer-DB sweep planning, OR (b) Phase 8.5 (ecosystem auth + Superset embedding per Backlog #30/#31).


Backlog

#ItemStatusBlocker
1Pipeline Management spec → approve → implementSpec in DraftPO review
2Risk Validation Module spec + implementNot startedSpec not written yet (next spec candidate)
3Deploy pssaas-staging to AKSLIVESQL MI firewall rule needed for Superset
4React frontend scaffoldNot startedLow priority
5Research PowerServer transaction semanticsNot startedTom's evaluation
6Research Odoo API for provisioningNot started
7Remaining 8 BestEx pipeline TODOsAvailable
8Jay: loan table customization patternsPartially answered (143+14)Follow-up on post-purchase tracking
9Greg: review risk deep diveNot startedGreg's availability
10Lisa: V1 feature surfaceNot started
11Synthetic test data for BestExNot started
12Tom: test LLPA plugin against PSX stagingNot startedAPI key (PSX ops) + staging access
13Website content review (Lisa / Greg / Jay)Drafts readyReviewer availability
14Re-add Docusaurus full-text searchBlockedNeeds compatible search plugin for pinned Docusaurus/webpack
15MIAC SRP evaluation endpoint (Rudy) — design + buildNot startedPending PO decision on PSX vs PSSaaS location
16Superset Phase 2 dashboards (Pipeline Health, Trading, Cost of Hedging, Cross Ratios)Not startedPhase 1 deployed first
17Deploy Phase 1 dashboards to PSX Superset stagingDONE
18PowerFill Module — Phase 1 (domain model + schema)Done
19PowerFill Module — Phase 2 (data access + preflight + views)Done
20PowerFill Module — Phase 3 (pre-processing procedures + orchestration)Done
21PowerFill Module — Phase 4 (constraint / carry-cost / lockdown CRUD + tenant-configurable preflight thresholds)DoneDeploy 004+005 on any DB provisioned before 2026-04-16 Phase 4 merge
21bPowerFill Module — Phase 7 (Reports / Recap Query APIs)Done8 GET endpoints + ADR-025 latest-Complete-wins; F-7-8 / 688-row Cash Trade Slotting pattern; A59-A62 added
21cPowerFill Module — Phase 8 W1 (Superset Dashboards)Done8 dashboards × 25 charts at PSX Superset IDs 13-20; A63-A64 added; F-8-BR-1 first empirical Backlog-re-read demonstration
21dPowerFill Module — Phase 8 W2 (React UI)DoneGreenfield React UI shipped (~50 source files under src/frontend/); ADR-026 + A67; sentinel phase-8-superset-react-ready-a54-fixed; awaits PO push + post-push staging-deploy click-through verification per W2 completion report's Capability × Environment matrix.
22PowerFill Module — Phases 5-9 (carry-cost calc, allocation engine, reports, UI, validation)Phase 5 done, Phase 6 COMPLETE (6a/6b/6c/6d/6e), Phase 7 COMPLETE, Phase 8 COMPLETE (W1 + A54 fix + W2), Phase 9 COMPLETE 2026-04-20 (Parallel Validation Harness at tools/parallel-validation/; Frame D Hybrid framing; A67 closed; A69 + A70 banked from first comparison run; sentinel phase-9-validation-ready; pending PO push).A54 + A56 RESOLVED. A66 NEW (Phase 9 / Greg-consultation carry-over). A65 NEW (Phase 9 parallel-validation harness probes; partially exercised — customer-DB sweep is operator-driven post-Phase-9). A69 NEW (Phase 9 first-run finding: state-dependent UE failure on non-empty post-pool_guide state on PS_DemoData; Greg/Tom consultation hook). A70 NEW (Phase 9 first-run finding: PS_DemoData has mixed PSSaaS/legacy proc-body state; production-cutover playbook needs explicit disposition). A63 still mitigates A62 for Phase 8 W1; A62 closure deferred to its own Backlog row #32 per Phase 9 carry-over scope.
32A62 closurepfillv_existng_pool_disposition view drift on PS_DemoData (legacy 14-col WITHOUT note_rate; PSSaaS-side 15-col WITH note_rate)Deferred from Phase 9 per Q2 confirmed scopeDecision needed: (a) deploy PSSaaS's 002_*.sql to PS_DemoData (may break consumers depending on the 14-col shape); (b) rename PSSaaS view to pfillv2_* (matches PSSaaS-namespacing convention; lower risk); (c) behavior-diff first then decide. The harness's Existing-Disposition endpoint hit surfaces the catch-and-degrade Note as the canonical observable.
33A69 root-cause investigation — sqlcmd-direct UE failure on non-empty post-pool_guide stateDeferred from Phase 9 first-run; Greg/Tom consultation hookPin the failing UE query line via PRINT-instrumented copy of 011_*.sql + RAISERROR-on-each-step diagnostic. Capture pfill_run_history.response_json for the PSSaaS run that ostensibly Completed. Resolves "PSSaaS silently swallows 207" vs "PSSaaS hits a different code path" hypothesis space.
34A70 production-cutover playbook step — onboarding a customer DB requires explicit disposition for the WITH ENCRYPTION procs (drop+redeploy from PSSaaS *.sql, OR behavior-diff confirmation)Deferred to Phase 10+ playbook draftingPhase 10+ playbook needs an explicit "verify PSSaaS-deployed proc bodies are running" step before first PSSaaS run on a new customer DB.
35Phase 9 ADR renumbering — RESOLVED in this commit batchDONE 2026-04-20Phase 9 kickoff initially mentioned ADR-027 as the Phase 9 harness ADR slot. During the Phase 9 dispatch window, the Collaborator independently authored ADR-027 (Superset Embedding Strategy) in commit ece500e. Per the canonical "ADRs are numbered sequentially and never renumbered" rule (first-committed wins), the Phase 9 ADR was renumbered to ADR-028 in this commit batch. ADR index + completion report + devlog + spec amendment + harness README all updated to reflect the renumbering.
23PS_DemoData schema deployment (001_CreatePowerFillSchema.sql)UNBLOCKED 2026-04-16 eveningkevin_pssaas_dev granted db_ddladmin on PS_DemoData (assumption A30 resolved). 17/17 tables already present, so 001 is a verified no-op when run; deploying still emits no DDL but is now safely possible. Phase 4 follow-up: deploy 004 + 005 (item #28b below).
24PS_DemoData views deployment (002_CreatePowerFillViews.sql)DEFERRED (perms unblocked; risk remains)Both expected views exist in PS_DemoData with WITH ENCRYPTION — definition unreadable via sp_helptext. Overwriting blind via CREATE OR ALTER VIEW is technically possible now but risky. Defer until either (a) we confirm the existing definitions match ours via behavior diff, (b) we rename our views to pfillv2_*, or (c) PO explicitly accepts overwrite.
25PS_DemoData procedures deployment (003_CreatePowerFillProcedures.sql)UNBLOCKED 2026-04-16 eveningDDL perms granted. 0 of our 3 procs exist in PS_DemoData (legacy procs may exist with same names but WITH ENCRYPTION — same blind-overwrite consideration as views). Verify before deploying.
26Investigate pfill_syn_* synthetic-trades subsystem (3 tables)Phase 6 prerequisiteDiscovered via PS_DemoData probing 2026-04-16; missing from Phase 1 reverse-engineering; Phase 6 Architect kickoff must include primary-source probe (assumption A28).
27Credentials in repo: rotate kevin_pssaas_dev password + scrub from infra/azure/HANDOFF-INFRA-AGENT.md and docs-site/docs/superset/setup-guide.mdSecurity cleanupPlaintext credentials currently published on staging Docusaurus. Mitigation: scoped user, sanitized data, but pssaas.staging.powerseller.com/docs/superset/setup-guide is internet-reachable.
28OIDC repo secrets configuration (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID)DONE 2026-04-16 eveningKevin added secrets; OIDC verified end-to-end at commit 5417d9a (docs deploy) and e90c494 (api deploy).
29Preflight default thresholds calibration (Kevin/Jay/Greg)Awaiting reviewPhase 2 plan Open Q #4; Phase 4 makes tenant-configurable
30Superset → pss-platform migration (PSX Infra-driven)DONE 2026-04-19Faster than projected. ~3 min cutover. Hostname bi.staging.powerseller.com UNCHANGED. All 20 dashboards / 56 charts / 77 datasets preserved (pg_dump immediately pre-cutover). Same Keycloak SSO + same superset OIDC client + same admin credentials + same Superset Python image SHA. Both data sources still work (PSX postgres cross-namespace via FQDN; SQL MI via VNet peering). Superset now runs in pss-platform namespace alongside keycloak, vault, mcp-server, with dedicated superset-db metadata pod (decoupled from PSX postgres). Old psx-staging superset pod scaled to 0; deployment retained for 24-hour rollback insurance. PSSaaS-side cleanup: hard-coded psx-staging namespace references in infra/superset/deploy-dashboards-flask.py docstring + AGENTS.md runbook + docs-site/docs/superset/powerfill-dashboards.md operational instructions all updated to pss-platform. Empirical re-verification: kubectl get pods -n pss-platform -l app=superset → 1/1 Running; dashboard 13-20 URLs all return HTTP 302 (Keycloak SSO redirect — auth-gated as designed) to anonymous probes.
31Phase 8.5 — PSSaaS joins ecosystem (Keycloak auth + embedded Superset SDK)EMPIRICALLY CLOSED 2026-04-20 ~14:40 UTC — auth boundary live + embedded SDK rendering Hub inline + PO browser-flow PO-verified end-to-end after ~3 hours of runtime-cutover-iteration (7 sequential failures: cookie_secret bytes / PKCE / audience / nginx buffer / Dockerfile.prod COPY / route prefix / ConfigMap convention). All fixes committed across 4c3b921 + a16e4a7 + 7d56244 + dcefc80 + ad94642 + 7b9a87c + da03740. Sentinel phase-8-5-ecosystem-ready LIVE on staging. Phase 8.5 PO milestone empirically achievable. One PSX-Infra-side optional follow-up: Keycloak Audience mapper add (allows removing the oidc_extra_audiences = ["account"] workaround; quality-upgrade not blocker).All 4 workstreams shipped in 1 Architect-session at ~1.5x complexity. W1 committed atomically as 4c3b921 per Reviewable Chunks; W2-4 + cross-cutting in a16e4a7. PSX Infra response 2026-04-20 (2026-04-20-psx-keycloak-pssaas-app-client-response; PSX commit 64dbec8): all 7 asks delivered (Keycloak pssaas-app client UUID 86a42170-2e30-403e-a2b9-d2c5f2961137 in psx-staging realm + tenant_id hardcoded mapper + cookie_secret bundled + dedicated pssaas-superset-credentials Secret + 5-item Superset pre-flight all PASS including PUBLIC_ROLE_LIKE half-day-debug-trap verified at DB level + dedicated pssaas-api-admin Superset user); 1 naming correction surfaced (realm is psx-staging NOT pss-platform); 2 deviations explicitly flagged + accepted PSSaaS-side. PSSaaS-side fixes applied this commit: realm rename (pss-platformpsx-staging) in oauth2-proxy.cfg + services.yaml ConfigMap mirror (LOAD-BEARING — without it oauth2-proxy fails OIDC discovery on first start); Superset Secret reference rename + key-name update; in-cluster URL switch per PSX recommendation; 2 banked process observations (realm-vs-namespace conflation as Writer-Time-vs-Reader-Time family member; PSX deviation-flagging as positive pattern). Sentinel phase-8-5-ecosystem-ready. 250 .NET tests pass + 6 skipped (+17 net-new vs Phase 9 baseline). ADR-027 Accepted; ADR-029 Accepted. A68 PARTIALLY RESOLVED. Completion report at powerfill-phase-8-5-completion. Originally added 2026-04-19 per PO direction. Ships oauth2-proxy + Keycloak realm/client for PSSaaS so /app/ and /api/ require authentication; replaces W2's "View in Superset" anchor links with @superset-ui/embedded-sdk <EmbeddedDashboard> component; closes the public-staging-URL security debt; folds in A68 long-term decoupling (TenantId from Keycloak claim). PSX Collab reply received 2026-04-19 (archived at 2026-04-19-psx-superset-embedding-relay) with file paths + 8 ranked gotchas + load-bearing Q3 architectural-mismatch correction (oauth2-proxy + static-site reference, NOT NextAuth + Next.js — our Vite static bundle is structurally PSX-Docs-shaped, not PSX-Next.js-shaped). ADR-027 (Proposed) drafted with PSX file-path references; pending Phase 8.5 Architect refinement at dispatch time. PSX Infra fallback offer is now moot (full reply landed). Estimated 2-3 Architect-sessions per the copied pattern. ADR-028 (PSSaaS Auth Strategy) folded into ADR-027 since the auth + embedding decisions are coupled. Dispatch sequencing: post-Phase-9-completion per PO sequence preference.
32Greg-demo data-richness questionWAITING ON JOE (path (b) is the load-bearing path) — PO reached out to Joe 2026-04-20 to source sanitizable customer data with syn-trade-eligible composition. Greg-demo deferred until that data lands. Path (a) Greg-demo narrative drafted at powerfill-greg-demo-narrative (commit e50bc8a) preserved as fallback / deferred reference material — not immediate-action workSurfaced 2026-04-20 by PO's first reaction to the empirically-closed Phase 8.5 W1 staging surface ("Hub seems fairly useless. Where do I see the good stuff?"). Per A66, PS_DemoData has no syn-trade arbitrage opportunities, so psp_powerfillUE rebuilds the user-facing tables empty after every Complete run by design intent — Hub dashboard renders 12+ rows of run history (the canonical proof-of-life), but per-report dashboards 14-20 (the analytical content) all render 0 rows. Consultation routing (PO direction 2026-04-20): Greg = hedging/risk + chunk-#2-selection (deferred until data lands); Rudy (junior dev currently in PowerFill code) = A54/A66/A69 technical-implementation consultation; Joe (IT/Infra/customer-migration) = LOAD-BEARING path-(b) data-sourcing (PO has reached out 2026-04-20); Tom = NOT immediate consultation source for any of A54/A66/A69 (remains canonical authority on Desktop App config patterns + Phase 10+ cutover-shape). Path posture (revised 2026-04-20 PO-direction): (a) Frame-the-empty-state-well demo — drafted at powerfill-greg-demo-narrative.md; DEMOTED to fallback-only-if-(b)-fails per PO direction "I won't bug Greg to look at PSSaaS PowerFill until we have data for reports." (b) Sanitized customer data via JoePROMOTED to the load-bearing path; PO outreach in flight; sanitization shape TBD; demo waits. (c) ELIMINATED — PS608 (Watermark TPO) does not use PowerFill per PO direction 2026-04-20; PowerFill chunk-#1 selection rationale TBD with PO; chunk-#2 selection conversation with Greg gains added load (Greg's Watermark-TPO PowerFill use is N/A so chunk-#2 selection is genuinely "what does Watermark-TPO actually use" vs original "which next-most-extracted module" framing). Demo-content disposition + chunk-#2 framing both wait on Joe + (eventually) Greg. NOT a Phase 8.5 follow-up; it's a Greg-demo-readiness item.

Key Documents

DocumentPathWhat It Contains
CLAUDE.mdCLAUDE.mdLean session context (read every session)
AGENTS.mdAGENTS.mdAgent memory — durable principles, lessons, preferences
.cursorrules.cursorrulesDevelopment rules (specs first, ADRs, conventional commits, PO governance)
Website draftsdocs-site/docs/website-drafts/Five drafts (overview + four modules); pending Lisa/Greg/Jay review
Desktop plugin (PSX LLPA)desktop-plugin/psxllpa/10 PB sources + README + API_REFERENCE.md
BestEx Specdocs-site/docs/specs/bestex-engine.mdApproved, 50+ requirements, 45 business rules
Pipeline Specdocs-site/docs/specs/pipeline-management.mdDraft, secondary marketing overlay model
Pricing Evolutiondocs-site/docs/ecosystem/pricing-integration-evolution.md3-phase PSX integration (buyer pricing → agency pricing → universal)
Xigo Requirementsdocs-site/docs/ecosystem/xigo-external-data-requirements.mdExternal data feeds + SA answers + rate sheet generator design
dataQollab Discoverydocs-site/docs/ecosystem/dataqollab-tba-pricing-discovery.mdTBA pricing already available via MBS Access
Market Data Retentiondocs-site/docs/ecosystem/market-data-retention-spec.md10 scheduled snapshots/day + event-driven
Value Discoverydocs-site/docs/ecosystem/value-discovery-strategy.mdGo-to-market strategy for Desktop App customers
PowerServer Coexistencedocs-site/docs/ecosystem/powerserver-coexistence.mdDesktop App → PowerServer → PSSaaS migration with plugin bridge
Plugins Deep Divedocs-site/docs/legacy/plugins-deep-dive.md32 Desktop App plugins analyzed
Loan Baselinedocs-site/docs/legacy/loan-table-baseline.md143 standard columns, all categorized
Product Licensingdocs-site/docs/legacy/product-licensing-modules.md5 Desktop App licensed modules
MIAC Analysisdocs-site/docs/legacy/miac-srp-workbook-analysis.mdThird Federal MIAC XLSX structure; SRP grids vs loan-level MSR; LLPA parity
Superset Designsdocs-site/docs/superset/dashboard-designs.mdBestEx Scorecard + Position Recon layouts, charts, cross-filter specs
Superset Setupdocs-site/docs/superset/setup-guide.mdConnection config, dataset creation for PSX Superset admin
Superset SQLinfra/superset/queries/15 SQL files (6 report translations + 9 dashboard charts)
PowerFill Deep Divedocs-site/docs/legacy/powerfill-deep-dive.mdLegacy plugin reverse-engineering: 25 files, 17 tables (corrected in Phase 1), 7 procedures, pool action semantics
PowerFill Specdocs-site/docs/specs/powerfill-engine.mdFull module spec: requirements, business rules, data contracts, 10-phase roadmap
PowerFill Assumptionsdocs-site/docs/specs/powerfill-assumptions-log.md68 interpretations (current as of 2026-04-20 commit 9a83b92): A1-A27 (Phase 0 legacy code reading); A28-A32 (PS_DemoData live-system probing); A33-A36 (Phases 4/5); A37-A40 (Phase 6 kickoff verification gate); A41-A45 (Phase 6a + pre-6b sweep); A46-A51 (Phase 6b — A1 revised; A9 RESOLVED via A47); A52-A54 (Phase 6c — A38 RESOLVED, A52 forward dep on UE syn table, A53 BR-3 spec drift, A54 RESOLVED 2026-04-19 via ADR-021 §Narrow Bug-Fix Carve-Out); A55-A57 (Phase 6d — A28 + A37 RESOLVED, A55 PS_DemoData empirical PK probe + F-6d-3 column-type correction, A56 RESOLVED 2026-04-19 with A54, A57 kickoff specificity reduces Truth Rot banked observation); A58 (Phase 6e — BR-9 cleanup scope split: 7 user-facing tables cleared, 4 syn-trades + log preserved for forensics per 6d D9 design intent — A66 amends with end-to-end-rebuild nuance); A59-A62 (Phase 7); A63-A64 (Phase 8 W1; A64 amended 2026-04-20 with platform-Superset migration tailwind note — multi-tenant Superset registration becomes architecturally cleaner under platform-Superset); A65-A66 (A54 fix — A65 banked observation: multi-pa_key + settlement-date variance are two distinct latent triggers; A66 NEW: UE clears + rebuilds-empty user-facing tables on syn-trade-empty datasets like PS_DemoData; Phase 9 / Greg-consultation followup); A67 (Phase 8 W2 — ReportContracts.cs XML doc-comment Truth Rot; F-W2-CONTRACT-1; deferred-cosmetic fix; Phase 9 forcing function); A68 (NEW 2026-04-20 — tenant-id-vs-config-slot conflation surfaced by post-W2-deploy F-W2-PSD-1; short-term Path γ disposition shipped via 8dba7b4 (Tenants__ps-demodata__ConnectionString env var on staging API); long-term decoupling natural fold into Phase 8.5 ecosystem-auth work per platform-tailwind note).
PowerFill A54 Fix Greg-Demo Readinessdocs-site/docs/handoffs/powerfill-a54-fix-greg-demo-readiness.mdCompletion report for the 2026-04-19 evening A54 fix. Includes copy-paste-ready "Bug as Feature" demo narrative for the PO to use during the Greg demo (5 slides). Documents the empirical-resolution arc, ADR-021 §Narrow Bug-Fix Carve-Out invocation, A65/A66 surfaced findings, post-fix dashboard row counts, Counterfactual Retro, and "What this enables next" recommendations for Phase 8 W2 + Phase 9.
PowerFill Phase 8 W2 Completiondocs-site/docs/handoffs/powerfill-phase-8-w2-completion.mdCompletion report for Phase 8 Workstream 2 (React UI). Documents the greenfield Vite + React + TS + Tailwind scaffold, 4-verdict freshness banner per A60 + A66 (BLUE-vs-YELLOW A66 distinction), 8 Phase 7 report pages with shared shell, K8s + GHA deploy pipeline, Capability × Environment matrix per practice #13, 3-instance-corroborated Backlog re-read pass, and Counterfactual Retro.
PowerFill Phase 9 Kickoffdocs-site/docs/agents/powerfill-phase-9-kickoff.mdArchitect kickoff for Phase 9 (Parallel Validation Harness). DISPATCHED + SHIPPED 2026-04-20 (commits b0f6469 + b548e78 + b350126). Harness at tools/parallel-validation/; first-run report surfaced A69.
PowerFill Phase 8.5 Kickoffdocs-site/docs/agents/powerfill-phase-8-5-kickoff.mdArchitect kickoff for Phase 8.5 (PSSaaS Joins Ecosystem Auth + Embedded Superset SDK). Drafted 2026-04-20 post-Phase-9-ship; ready to dispatch as the LAST demo-blocker before Greg-demo readiness per PO sequence preference. 4 workstreams: (1) oauth2-proxy + Keycloak realm/client; (2) embedded SDK in React UI replacing W2 anchor links; (3) .NET 8 guest-token-mint endpoint + Superset embedded-dashboard registration script; (4) A68 long-term decoupling fold-in (TenantId from Keycloak claim). Inheritance from ADR-027 (Proposed) + cross-project-relays archive entry (PSX Collab embedding-pattern reply).
PowerFill React UIsrc/frontend/Greenfield Vite + React + TypeScript + Tailwind v4 + React Router 7 operator UI. ~50 source files; 270KB gzipped JS. Served at https://pssaas.staging.powerseller.com/app/ post-push. See ADR-026.
Process Discipline (canonical)docs-site/docs/agents/process-discipline.mdEcosystem-wide discipline: 10 practices, 13 antipatterns, nomination template, signal-based cadence. Current revision v4.1.
PSX Relay Stubdocs-site/docs/agents/psx-relay-stub.mdShort block Kevin relays to PSX/MBS Access Collaborator agents so they reference the canonical
Agent Roles Overviewdocs-site/docs/agents/README.mdMulti-agent structure: Collaborator / Architect / Developer boundaries
Collaborator Contextdocs-site/docs/agents/collaborator-context.mdCollaborator role definition and operating rules
Architect Contextdocs-site/docs/agents/architect-context.mdSystems Architect role definition, including Required Delegation Categories
Developer Contextdocs-site/docs/agents/developer-context.mdDeveloper role definition (fast subagent, manual relay, or self)
Handoff Prompt Templatesdocs-site/docs/agents/handoff-prompts.mdSeven templates for role transitions and escalations
PowerFill Architect Kickoffdocs-site/docs/agents/powerfill-architect-kickoff.mdOriginal prompt used to bootstrap the Architect on PowerFill Phase 1
PowerFill Phase 1 Nominationdocs-site/docs/agents/powerfill-phase-1-antipattern-nomination.mdPhase-0 Truth Rot nomination record
PowerFill Phase 2 Gate Clarificationdocs-site/docs/agents/powerfill-phase-2-gate-clarification.mdPrimary-Source Verification Gate scope clarification (v3.1)
Delegation Skip Nominationdocs-site/docs/agents/delegation-skip-antipattern-nomination.mdv4 nomination record

Git State

Main branch. 3 LOCAL commits ahead of origin/main (PO pushes; Architect commits only):

  1. 4c3b921 (Phase 8.5 W1 atomic): oauth2-proxy + Keycloak realm/client setup; cross-project-relay request to PSX Infra; W1 checkpoint Architect Report
  2. a16e4a7 (Phase 8.5 W2-4 + cross-cutting wrap-up): embedded SDK in React UI; .NET 8 guest-token-mint endpoint + registration script + tests; A68 long-term decoupling code shape + tests + ADR-029; sentinel bump + spec amendment + ADR-027 status flip + ADR index + completion report + devlog + session-handoff bump + Greg-demo readiness amendment
  3. (pending Architect commit, this session): PSX Infra response acknowledgment + PSSaaS-side fixes (realm rename pss-platformpsx-staging in oauth2-proxy.cfg + services.yaml; Superset Secret reference rename + in-cluster URL switch; oauth2-proxy-secrets.yaml.example reframing; appsettings env-var-override comment; 2 banked process observations; session-handoff Backlog #31 + Git State updates)

Recent push history (most recent first):

  • (pending Architect commit, this session) — PSX Infra response received + PSSaaS-side fixes (realm rename + Superset Secret rename + 2 banked process observations)
  • a16e4a7 2026-04-20 (LOCAL; pending push) — Phase 8.5 W2-4 + cross-cutting wrap-up (42 files, 3156 insertions; 18 new files; 250 .NET tests pass; pre-push docs-build GREEN)
  • 4c3b921 2026-04-20 (LOCAL; pending push) — Phase 8.5 W1 atomic commit (oauth2-proxy + ingress + GHA + cross-project-relay request + W1 checkpoint report)
  • f1413a8 2026-04-20 — Phase 8.5 kickoff drafted + session-handoff aligned
  • 31b5d59 2026-04-19 — bank PSX Collab close-out — adopt "Writer-Time vs Reader-Time Truth Divergence" family heading
  • 9a83b92 2026-04-20 — backlog #30/#31 + A64/A68 platform-tailwinds (PO direction during post-W2-deploy session)
  • 8dba7b4 2026-04-20 — Path γ for F-W2-PSD-1 (Tenants__ps-demodata__ConnectionString env var on staging API + A68 banked)
  • d4d294e 2026-04-19 — F-W2-PSD-1 fix (PS608 removed from tenant dropdown + tenant ID → ps-demodata + case-insensitive TenantRegistry)
  • 1de964d 2026-04-19 — Phase 8 W2 docs (ADR-026 + spec + A67 + completion report + devlog + handoff)
  • 9be1b8e 2026-04-19 — Phase 8 W2 infra (frontend Deployment + Service + ingress /app path + GHA workflow)
  • 10f9891 2026-04-19 — Phase 8 W2 React UI scaffold (~50 source files under src/frontend/)
  • f4531ae 2026-04-19 — W2 kickoff body scrub (post-4b08b51 follow-up)
  • 4b08b51 2026-04-19 — W2 kickoff inherited-context refresh (post-A54-fix + canonical Claim-vs-Evidence family)

GHA deploy-staging rolled all of the above to pssaas-staging namespace; sentinel phase-8-superset-react-ready-a54-fixed live on staging API; https://pssaas.staging.powerseller.com/app/ operational.

Local-only (uncommitted): Phase 9 kickoff at docs-site/docs/agents/powerfill-phase-9-kickoff.md — drafted this session, awaiting commit + push. Drafting-but-not-pushing-yet of process-discipline.md updates for the 3 banked observations (Subagent Output Defended Beyond Scope; Convention Conflation Under Low-Corroboration Count; Single-Probe Confidence) — accumulating for next discipline-doc revision.


Rules (Always Enforce)

  1. Specs before code. No development without a specification.
  2. Conventional commits. feat:, fix:, docs:, chore:, test:, refactor:
  3. Never push. Only the Product Owner pushes.
  4. Post-completion checklist. Devlog, glossary, ADRs, Arc42, specs — check all before committing.
  5. decimal for money. Never float or double in C#.
  6. Tenant isolation. Every query scoped to authenticated tenant's database.
  7. Read CLAUDE.md and this handoff at the start of every resumed session.