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-readyLIVE on staging athttps://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):
# Symptom Root cause Family classification Fix commit 1 oauth2-proxy CrashLoopBackOff ( cookie_secret 44 bytes vs required 16/24/32)PSX Infra delivered openssl rand -base64 32output literallyMember 3 instance 2 (answerer→asker) live-patch + ad946422 OIDC callback Missing parameter: code_challenge_methodKeycloak PKCE S256 required without matching client config Member 3 instance 3 live-patch + ad946423 OIDC callback 500 ( audience [account] does not match)Keycloak default audience claim doesn't include client itself Member 3 instance 4 live-patch + ad946424 nginx-ingress 502 ( upstream sent too big header)proxy_buffer_size default too small for JWT+9-roles cookie Generic integration tax live-patch + ad946425 React UI 404 on /api/superset/guest-tokenModules.Superset.dllmissing from runtime image (Dockerfile.prod COPY-set incomplete)PSSaaS-internal artifact-vs-artifact ad946426 Same 404 post-Dockerfile-fix Endpoint registered at /api/superset/superset/guest-token(double-prefix from nested MapGroup + relative path)PSSaaS-internal artifact-vs-artifact 7b9a87c7 503 ( dashboard_key 'hub' has no UUID configured)ConfigMap injected flat keys ( hub); .NET binding expectedPowerFillEmbedUuids__HubPSSaaS-internal artifact-vs-artifact live-patch + da03740Member 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:
- PSX Infra Audience mapper add (removes the
oidc_extra_audiences = ["account"]workaround; quality-upgrade not blocker)- PSX Infra acknowledgment relay (W1-actually-closed framing + the audience-mapper request + meta-rule-earned-receipts framing)
- 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 commit64dbec8; PSSaaS-side response file in working tree pending PSSaaS push). What shipped THIS sub-session (post-PSX-response Architect fixes; pending PO push):
- REALM-NAME LOAD-BEARING FIX —
infra/oauth2-proxy/oauth2-proxy.cfg+infra/azure/k8s/pssaas-staging/services.yamlConfigMap mirror updated:oidc_issuer_urlfromhttps://auth.powerseller.com/realms/pss-platform→https://auth.powerseller.com/realms/psx-staging. Without this fix oauth2-proxy fails OIDC discovery on first start. Original W1 commit4c3b921had the wrong realm name from PSSaaS Architect's unverified inference (K8s namespace name = realm name) — PSX Infra's response empirically confirmed onlymaster,psx-staging,pss-servicesrealms exist; resolved by creatingpssaas-appinpsx-staging(the cross-project staging realm).- SUPERSET-CREDS SECRET REFERENCE FIX —
infra/azure/k8s/pssaas-staging/services.yamlupdated to reference the actual delivered Secret namepssaas-superset-credentials(PSX's chosen name; cleaner separation than the original ask of patchingpssaas-secrets) with the actual delivered key names (SUPERSET_URL,SUPERSET_ADMIN_USERNAME,SUPERSET_ADMIN_PASSWORD). Switched .NET BaseUrl to use the in-cluster URLhttp://superset.pss-platform.svc.cluster.local:8088per PSX's explicit recommendation — avoids TLS/ingress overhead + stays off public internet for the server-to-server 3-step handshake. Public URLhttps://bi.staging.powerseller.comremains inappsettings.Staging.jsonas a sensible pre-Secret-applied fallback (env vars win in ASP.NET Core's standard config-builder ordering).oauth2-proxy-secrets.yaml.examplereframed as historical-reference + as-delivered-shape documentation. Live cluster Secret was direct PSX Vault → K8s injection (PSX bundled bothclient_secretANDcookie_secretin same Secret per their explicitly-flagged-and-justified deviation; accepted PSSaaS-side); template stays for Phase 10+ cloning + DR.appsettings.Staging.jsonSuperset section gets a_commentexplaining the env-var override.- 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".- 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.yamlfor first-deploy of oauth2-proxy Deployment):
curl -I https://pssaas.staging.powerseller.com/app/→ expect HTTP 302 to Keycloak login page onauth.powerseller.com/realms/psx-staging/...curl -I https://pssaas.staging.powerseller.com/api/health→ expect HTTP 401curl -I https://pssaas.staging.powerseller.com/docs/→ expect HTTP 200 (UNCHANGED)- Browser login flow end-to-end → expect post-login
/app/200 with React UI rendering + JWT containstenant_id: ps-demodataclaim (verifiable via Application → Cookies in DevTools)- PSSaaS API
/api/superset/guest-tokenend-to-end (post-register-powerfill-embeds.pyrun; ConfigMap populated): operator clicks any report → embedded dashboard renders inlineBacklog #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_SECRETon Superset uses the hardcoded fallback insuperset_config.pyrather 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-readyand historical-a54-fixedsub-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 as4c3b921per Reviewable Chunks; W2-4 + cross-cutting ina16e4a7; pending PO push of both):
- 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/tooauth2-proxy:4180;/docs/UNCHANGED) +oauth2-proxy-secrets.yaml.exampletemplate +.github/workflows/deploy-staging.yamlrolling-restart step + cross-project-relay request to PSX Infra atdocs-site/docs/agents/cross-project-relays/2026-04-20-pssaas-keycloak-pssaas-app-client-request.md+ W1 checkpoint Architect Report atdocs-site/docs/handoffs/powerfill-phase-8-5-w1-checkpoint.md- W2 (Embedded Superset SDK in React UI) —
@superset-ui/embedded-sdk@^0.3.0added (lazy-loaded atlib-Cb7LCDYX.js6.82KB / 2.78KB gzipped chunk); newsrc/frontend/src/components/EmbeddedDashboard.tsx(PSX SupersetEmbed.tsx-shape; useEffect chain; iframe-sizing containerRef polling; cleanup contract); anchor-link → embedded-component swaps inreportShell.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_messagerender unchanged);App.tsxHeader tenant-picker DISABLED with tooltip +Sign outlink added- 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 ofIHttpClientFactoryregistration in the codebase per Phase 8.5 plan §2 Consolidation Gate);SupersetOptions+PowerFillEmbedUuidsIOptions bindings;appsettings.Staging.json+services.yamlenv-from-Secret + configMapRef wiring; placeholder ConfigMappowerfill-embed-uuids-configmap.yaml.infra/superset/register-powerfill-embeds.pyDELEGATED to fast subagent per plan §6 — Flask app context primary path (matchesdeploy-powerfill.py+deploy-dashboards-flask.py); subagent output passed the W2-PS608-antipattern first-question check; no scope drift- W4 (A68 long-term decoupling code shape) — new
Tenantsealed record atsrc/backend/PowerSeller.SaaS.Infrastructure/Data/Tenant.cs;TenantRegistry.Resolve(identity)returnsTenant?tuple;TenantMiddlewareresolution-precedence INVERTED (OIDCtenant_idclaim fromX-Forwarded-Access-Tokenwins over legacyX-Tenant-Idheader per ADR-029); internalExtractClaimFromAccessTokenhelper does base64url JWT-payload decode (no signature validation per trust-of-gateway model — oauth2-proxy already validated);InternalsVisibleTofor Api.Tests- ADR-029 (NEW; Accepted) at
docs-site/docs/adr/adr-029-pssaas-tenant-identity-strategy.mddocuments the long-term shape + the v1 code-shape-only PO disposition + the JWT trust-of-gateway model + 4 alternatives + Phase 10+ follow-up checklist- 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
- A68 PARTIALLY RESOLVED in
docs-site/docs/specs/powerfill-assumptions-log.mdwith the 2026-04-20 status update block at top of entry- Sentinel bumped
phase-9-validation-ready→phase-8-5-ecosystem-readyinPowerFillModule.cs+SupersetModule.cs- Spec amendment: new Phase 8.5 row in Phased Implementation table at
docs-site/docs/specs/powerfill-engine.md- ADR index updated at
docs-site/docs/arc42/09-architecture-decisions.md(ADR-027 → Accepted; ADR-029 added)- 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)- Devlog at
docs-site/docs/devlog/2026-04-20-powerfill-phase-8-5.md- Greg-demo-readiness handoff amended with two load-bearing slot-in slides per kickoff
Empirical first-run state:
dotnet build PowerSeller.SaaS.slnclean (0 warnings, 0 errors; 11 projects compiled);dotnet test PowerSeller.SaaS.slnclean (250 passed + 6 skipped + 0 failed; was 233 pre-Phase-8.5; +17 net-new: 8 SupersetGuestTokenClient + 9 TenantMiddleware);npm run buildclean (272.69KB JS gzipped; SDK lazy-loaded chunk separated);npm run typecheck+npm run lintclean. Pending PSX Infra collaboration: Keycloakpssaas-appclient + client_secret + realm-sidetenant_idmapper + 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+InternalsVisibleTois 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-fixedsub-suffix per kickoff §"Cross-cutting"; A54 closure is now historical). What shipped THAT session (Phase 9; pending PO push):
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 runtimedocs-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 additiondocs-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 commitece500eduring the Phase 9 dispatch windowsrc/backend/PowerSeller.SaaS.Modules.PowerFill/Contracts/ReportContracts.cs— A67 closure (9 XML doc-comment paths re-aligned)src/backend/PowerSeller.SaaS.Modules.PowerFill/PowerFillModule.cs— sentinel bumped tophase-9-validation-readydocs-site/docs/specs/powerfill-engine.mdPhase 9 row marked DONE; new Phase 10 row for production cutoverdocs-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)docs-site/docs/handoffs/powerfill-phase-9-completion.md— W2-shaped completion report with full Capability × Environment matrix per practice #13docs-site/docs/devlog/2026-04-20-powerfill-phase-9.md— devlog entry per template-7Empirical first-run state: PSSaaS run
9312a638-cd21-4485-b42e-ee8dc02be0d0Complete 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 newRowVerdict.INCOMPARABLEclassification (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; onlypsp_powerfill_pool_guideis 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.mdready 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-vmss000000separate node pool 2026-04-20; sentinelphase-9-validation-readyLIVE 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.j2template'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-fixedwas live on staging). What shipped that session (8 commits, all pushed):
4b08b51+f4531ae— W2 kickoff prep (post-A54-fix + canonical-family inherited context refresh)10f9891+9be1b8e+1de964d— W2 ship (Architect): React UI undersrc/frontend/, K8s + GHA deploy pipeline, ADR-026, A67, completion report- 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-hyphenatedps-demodatato match backend convention; case-insensitiveTenantRegistryfor hygiene)8dba7b4— Path γ for F-W2-PSD-1 fallout (Tenants__ps-demodata__ConnectionStringenv var added to staging API Deployment so request-time tenant ID matches existingpfill_run_historyrow 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 notesEmpirical staging state: API sentinel
phase-8-superset-react-ready-a54-fixed;/app/HTTP 200 with<title>PowerFill — PSSaaS Operator</title>;/app/healthz200;GET /runswithX-Tenant-Id: ps-demodatareturns 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 intopowerfill-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-stagingon sharedpss-cluster(alongsidepsx-stagingandpss-platform) - Images: GHCR at
ghcr.io/kevinsawyer/powerseller-saas/{docs,api} - CI/CD: GitHub Actions — path-filtered builds,
kubectl set imagedeploy - 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.localto the dev server, so local Docker needs a hosts override to hit127.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, andAPI_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.
| ADR | Title | Status |
|---|---|---|
| 001 | Backend — .NET 8 / C# | Accepted |
| 002 | Frontend — React + TypeScript | Accepted |
| 003 | Cloud — Azure-Preferred, Vendor-Agnostic | Accepted |
| 004 | Architecture — Modular Monolith First | Accepted |
| 005 | Database — SQL MI, Database-Per-Tenant | Accepted |
| 006 | Schema — Preserve Initially | Accepted |
| 007 | Audience — New Customers First | Accepted |
| 008 | UX — Two Modes (Modern + Power) | Accepted |
| 009 | Docs — Docusaurus | Accepted |
| 010 | Documentation — Arc42 + ADRs + Specs | Accepted |
| 011 | Ecosystem Product Boundaries | Accepted |
| 012 | Odoo as Commercial Layer | Accepted |
| 013 | Identity Strategy | Proposed |
| 014 | Backend Language Divergence (.NET vs Python) | Accepted |
| 015 | Desktop App Coexistence | Accepted |
| 016 | Nginx Proxy + Docker Compose Profiles | Accepted |
| 017 | Ecosystem Hostnames (*.powerseller.local) | Accepted |
| 018 | Local SQL Server for Development | Accepted |
| 019 | PSX-to-SaaS BestEx Integration | Proposed |
| 020 | Shared Kubernetes Cluster with PSX | Proposed |
| 021 | PowerFill Port Strategy (hybrid T-SQL + C#) — Amended 2026-04-19 with §Narrow Bug-Fix Carve-Out (A54 = canonical first instance) | Proposed (amended) |
| 022 | PowerFill Allocation Algorithm (port iterative passes) | Proposed |
| 023 | PowerFill Constraint Model (preserve legacy tree) | Proposed |
| 024 | PowerFill Async Run Pattern (BackgroundService + Channel) | Proposed |
| 025 | PowerFill Report API Pattern (Phase 7 latest-Complete-wins) | Proposed |
| 026 | Frontend Framework + Build Pipeline (Phase 8 W2 Vite + React + TS + Tailwind) | Proposed |
Specs
| Spec | Status | Priority |
|---|---|---|
| BestEx Engine | Approved, Implemented | Tier 1 — done |
| Pipeline Management | Draft | Immediate — WTPO's near-term need |
| PSX BestEx Integration | Draft | Future — when WTPO adds agency delivery |
| Risk Validation Module | Not written yet | Next spec — discussed; validate Desktop App LLPA integration when written |
| PowerFill Engine | Draft (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
| Person | Role | Relevance |
|---|---|---|
| Kevin Sawyer | CTO, 40% owner, Product Owner | Makes all decisions |
| Lisa | CEO, 60% owner, MWFI CEO | Domain authority, strategic direction |
| Greg | Contract President, prior owner | Hedging/risk knowledge (time-limited) |
| Jay | Ops Manager | Power user, customer advocate, secondary marketing experience |
| Tom | Senior Dev | PowerBuilder veteran, ~5 years to retirement, maintains Desktop App |
| Rudy | Junior Dev | Migrating source control, eager for SaaS, 10-15 year horizon |
| Joe | IT / Infrastructure | Azure, Docker, security, customer migration |
Strategic Discoveries (This Session)
-
WTPO's immediate need is NOT BestEx — it's CRA spread arbitrage on PSX. BestEx is for future agency delivery.
-
Pipeline Management is the real near-term PSSaaS need — post-purchase tracking that the Desktop App handles via BidMgr plugin.
-
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.
-
The Desktop App's Data Manager is the foundational module but its ETL (1,600+ SQL conversion rules) is painful. PSX replaces this.
-
BidMgr and bid_pkg are different modules — BidMgr is inbound (seller tapes), bid_pkg is outbound (investor bid packages).
-
dataQollab already provides TBA pricing via
api.mbsmkt.com— no new vendor needed for Xigo. -
Agency LLPAs are public Excel files — PSX ingests them (ADR-098), evaluates them via stacking engine with
buyer_id = "FNMA"/"FHLMC". -
Loan table baseline: 143 standard columns + ~12 custom per customer. WTPO has 14 custom columns.
-
Rate sheet generation needed NOW for Xarbi (not just future Xigo) — reference buyer price minus margin.
-
WTPO's generated rate sheet is stored as an extracted_profile in PSX with
participant_type = 'principal'. -
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.
-
dataQollab (
api.mbsmkt.com) already provides TBA pricing data — no new vendor needed for Xigo; PowerSeller is licensed to use it. -
WTPO needs rate sheet generation now for Xarbi (reference buyer price minus margin), not only for future Xigo.
-
WTPO's generated rate sheet in PSX: stored as
extracted_profilewithparticipant_type = 'principal'andbuyer_id = "watermark-tpo". -
PSX solution architect: Xarbi and Xigo share the stacking engine — agency LLPAs use the same grid model with
buyer_id = "FNMA"/"FHLMC". -
SpecialFeatureCode (e.g. HomeReady SFC 900) is not available at Risk Manager stage — assigned at commitment/delivery time. Desktop App exposes
feature_code_001–006on pools/instruments, not on loans. -
Desktop App licensing — five modules by name: Data Manager, Secondary Manager, Risk Manager, Post-Closing Manager, AppRunner Manager.
-
Website content — drafts written for all four product modules plus overview; pending review by Lisa, Greg, and Jay.
-
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.
-
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.
-
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/loantables), 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. -
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. -
Superset dashboards designed from Desktop App reports.
-
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.
-
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.
-
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 atdocs-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. -
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. -
PowerFill module Phase 1 complete (2026-04-16).
PowerSeller.SaaS.Modules.PowerFill.NET project scaffolded with 17 EF Core entities mapping to the 17 legacypfill_*tables (Phase 0's stated count of 13 was wrong — direct DDL extraction fromn_cst_powerfill.sruline 6004 revealed 17 tables and one misnamed table,pfill_epci_paramsnotpfill_ect_params). Idempotent schema deployment SQL atsrc/backend/PowerSeller.SaaS.Modules.PowerFill/Sql/001_CreatePowerFillSchema.sql. Integration testSchemaScriptIntegrationTestsverified round-trip entity↔schema compatibility against the Dockerpssaas-dbSQL 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). -
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_tradesideview was missing from Phase 0 docs — NVO creates two views, not one; (b) Phase 0 citedpscat_securities_sec_ruleswhich doesn't exist — NVO usespscat_securitization_rules; (c)pssaas-dbwas missing 8 tables Phase 2 reads (addressed by extendinginfra/sql/init/seed-schema.sql). All three corrected in-place. Shared entity extraction (Choice A3): newPowerSeller.SaaS.SharedDomainproject holdsLoan,Instrument,ProfileInstrumentMapping,TodaysPrice— consolidates what would have been duplicate paths between BestEx and PowerFill; BestEx tests pass unchanged. Preflight surface: 9 composable checks orchestrated byPowerFillPreflightService, exposed atPOST /api/powerfill/preflight. Views: both transcribed from NVO intoSql/002_CreatePowerFillViews.sql, deployed viadocker-compose.ymlmount +setup.shper-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. -
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 ENCRYPTIONpreserved):psp_add_to_pool_lockdown_guide,psp_pfill_ect_params,psp_pfill_trade_params. C# orchestration:PowerFillPreprocessServiceinvokes the 3 inw_powerfill.srw::ue_perform_preprocessorder, stops on first failure, reports per-step status; no explicit transaction (matches Desktop App; all 3 procs are self-idempotent). Exposed atPOST /api/powerfill/preprocess. Four Phase-0 Truth Rot findings corrected with explicit Gate Output Action disposition format (first use of v4.1): F1 — procedure namedpsp_pfill_ect_paramseven though table ispfill_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_gridmissing frompssaas-db; F4 —pscat_poolsandpscat_trades_pools_relationmissing 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 pendingkevin_pssaas_devcredentials (Backlog #25). -
PS_DemoData live-system probing — five new findings (2026-04-16). Collaborator attempted to deploy
001/003to PS_DemoData usingkevin_pssaas_dev. Discovered: (A28) 3pfill_syn_*synthetic-trades tables missing from spec — they live outsideof_update_databaseand are populated by procedures the deep dive didn't cover; Phase 6 prerequisite. (A29)CHAR(N)declared in001actually exists asVARCHAR(N)in PS_DemoData — confirms A26 in opposite direction; trailing-space semantics differ. (A30)kevin_pssaas_devlacks DDL perms (db_datareader+db_datawriteronly); cannot CREATE PROCEDURE/TABLE/VIEW; PS_DemoData deployments blocked. (A31)pfill_carry_costalready has 295 production rows in PS_DemoData;001'sIF OBJECT_ID IS NULLguards correctly preserve them. (A32) An idempotent DDL script can "succeed" without running any DDL —001returned exit code 0 because all 17 expected tables already exist; if any had been missing, the sameMsg 262: CREATE PROCEDURE permission deniedwould 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.,PRINTinside eachIF OBJECT_ID IS NULLguard). 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 localpssaas-dbcontainer; PS_DemoData deployment is a separate workstream. -
PowerFill module Phase 4 complete (2026-04-16; commit
1f2caeainitial + follow-upfix:for verification gap). SQL004_CreatePowerFillPreflightSettings.sql+005_AddPfillConstraintsRowversion.sql(PRINT per A32). EF + services +ConfigurationEndpointsfor 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).PowerFillPreflightServicemergespfill_preflight_settingsbefore checks; falls back to built-in defaults if004not deployed.GET /settings/preflightalways returns a value with asourcefield (tenant/defaults/builtin).lock_poolnormalized to'y'/'n'on create/update/bulk. F3: spec line 83 "lockdown" delete rule not schema-joinable — interim 409 whenpfill_constraint_sec_rule_relrows exist; documented in assumptions A33, spec, andpowerfill-phase4-f3-architect-escalation. Race-condition betweenDeleteConstraintAsyncandAddSecRuleAsyncacknowledged in code XML doc + A33 (Phase 6 to serialize). Verification: 87/87 tests pass (32 BestEx + 1 Api + 54 PowerFill including 4 SQL integration viapssaas-db);dotnet buildclean (0 warnings). Existing dev DBs created before Phase 4 do NOT block usage — preflight degrades to built-ins — but should still get004/005applied for tenant-configurable behavior. Process discipline regression caught and fixed: the initial Phase 4 commit shipped without runningdotnet build/dotnet testbecausedotnetwasn't on the agent shell PATH; the follow-upfix:commit ran the build inside thepssaas-apicontainer, found 4 real failures (rowversion nullability, key-modification onReload(), seed-schema path inside container) and resolved them. -
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) into009_CreatePoolGuideProcedure.sql(3,274 lines; subagent transcription clean first-attempt).PowerFillRunServiceextended with Step 5 (pool_guide);RunSummarygainspool_guide_count; sentinel bumped tophase-6c-pool-actions-ready. A38 RESOLVED:psp_pfill_insert4_pool_guideis invoked from insidepsp_powerfill_pool_guidebody at NVO 11130 (empirical NVO trace; both procs deploy together in 009). 3 new assumptions: A52 (pool_guide forward dep on UE-populatedpfill_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_1300PK violation on multi-pa_key loan/trade pairs; verbatim port preserves;pool_guide_count = 0on 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. -
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_history14-col audit table + filtered unique indexux_pfill_run_history_tenant_activefor BR-8 + cursor pagination index per Q1/Q2/Q3/Q7 PO-confirmed defaults),PowerFillRunHistoryEF 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),IRunProgressSinkcallback for status transitions,RunStatusextended 2→7 values with active-set encoded BOTH in SQL filter predicate ANDPowerFillRunHistoryService.ActiveStatuses(contract tests pin both byte-for-byte).POST /runreturns 202 Accepted +RunSubmissionResponse+Locationheader (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 fromresponse_jsonsnapshot),POST /runs/{run_id}/cancel. Sentinel bumped tophase-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. -
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-endCompletePowerFill 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 tophase-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 ofpfill_powerfill_guiderevealed trade36177868had 4 rows with 3 distinct settlement_dates across loans → actual fan-out source was thept13INNER JOIN qualifying ontrade_idonly 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: run43e8f148-3d1f-4c40-9f76-a43f84efdfb9Status=Complete in 30s wall-clock withpool_guide_count: 515, Step 6 (ue) succeeded, 12 events inpfill_powerfill_log. Reproducible (run7c9dfe50-...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'spfill_cash_market_mapper 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 atpowerfill-a54-fix-greg-demo-readinesswith copy-paste-ready "Bug as Feature" demo narrative for the PO. -
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 attools/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-dependentpsp_powerfillUESqlException 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; onlypsp_powerfill_pool_guideis 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 inece500eduring Architect dispatch window); A67 closed (ReportContracts.csXML doc-paths swept from/runs/{run_id}/reports/<name>→/runs/{run_id}/<name>to matchRunEndpoints.cs; comment-doc-only edit); sentinel bumpedphase-8-superset-react-ready-a54-fixed→phase-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/apipost-Architect-push timed out with0/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 nodeaks-userpool1-16401317-vmss000000(separate node pool); pending API pod scheduled + rolled naturally; sentinelphase-9-validation-readyLIVE 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/healthHTTP 200, all unauthenticated as designed for current state. (c) Cross-project-relay exchanges closed durably: PSX Infra Superset → pss-platform migration acknowledged +psx-stagingnamespace references swept frominfra/superset/deploy-dashboards-flask.py+AGENTS.md+docs-site/docs/superset/powerfill-dashboards.md(commitf920668); A64 platform-tailwind note marked RESOLVED (commit9a83b92). 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 entry2026-04-19-psx-superset-embedding-relay.mdmirrors the Claim-vs-Evidence family archive shape (commitece500e); 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 (commit31b5d59). (d) Phase 8.5 kickoff drafted atdocs-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. -
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: appliedinfra/azure/k8s/pssaas-staging/services.yaml+pssaas-ingress.yamlto live cluster (frontend Deployment + Service created; ingress reconfigured with/apppath; pod healthy in 20s); empirically smoke-tested staging — sentinel API returnsphase-8-superset-react-ready-a54-fixed,/app/HTTP 200 with<title>PowerFill — PSSaaS Operator</title>, asset paths correctly prefixed/app/assets/...,/docs/+/api/healthregression checks 200 (no collateral damage). (b) F-W2-PSD-1 finding: React UI's tenant dropdown sentPS_DemoDataPascalCase + 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); backendTenantRegistryis case-sensitive Dictionary lookup — every UI request 401'dUnknown tenant. (c) Fixd4d294e: removed PS608 from dropdown (security: unauth staging URL must not point at live customer DB); renamed tenant ID to lowercase-hyphenatedps-demodatato match backend convention; addedStringComparer.OrdinalIgnoreCaseonTenantRegistryfor hygiene; rewrotetenantConstants.tsdoc-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 showconfirmed same MI;@@SERVERNAMEcheck confirmed same engine; private-endpoint reaches the populated 11,674-loan PS_DemoData by Azure design). Root cause was application-side:pfill_run_historyrows taggedtenant_id='ps-demodata'(Architect's local-route convention) vs staging queryingWHERE tenant_id='default'(staging's only configured slot). (e) Path γ8dba7b4: addedTenants__ps-demodata__ConnectionStringenv var to staging API Deployment (referencing same existing secret value via 3rd reference; no new secret needed); applied viakubectl apply -f services.yaml; rolled cleanly; staging API now returns 12 historical runs (3 Complete + 7 Failed + 2 Cancelled) underX-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 frompsx-staging→pss-platformnamespace (stateless shared resource, co-tenant with Keycloak); PSX Infra-driven; PSSaaS is downstream consumer (re-register dashboards 13-20 + updatesrc/frontend/src/config/supersetDashboards.tsbase URL atomically when migration completes). (h)9a83b92commits: 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 atdocs-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 intopowerfill-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. -
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 typecheckclean;npm run lintclean 0/0;npm run buildclean — 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 viauseEffectAbortController 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. Newsrc/frontend/Dockerfile.prod(multi-stagenode:22-alpinebuild →nginx:alpineserve at/app/; mirrorsdocs-site/Dockerfile.prod); newfrontendDeployment + ClusterIP Service ininfra/azure/k8s/pssaas-staging/services.yaml; ingress path/appadded (per F-W2-BR-3 —/docs/+/api/already taken;/app/chosen for the operator workspace); GHAdeploy-staging.yamlextended withfrontendpath-filter +build-frontendjob + idempotent rollout step (with first-deploykubectl get deployment/frontendguard). Sentinel bumped fromphase-8-superset-ready-a54-fixedtophase-8-superset-react-ready-a54-fixed(suffix-style preserves the A54-fix sub-suffix per thecf8ef8bcanonical pattern; 1-line change inPowerFillModule.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.csXML doc-comments document/reports/<name>paths that don't exist in routes; actualRunEndpoints.csregistrations 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 atpowerfill-phase-8-w2-completion. Phase 9 (Parallel Validation) is the next phase. -
PowerFill Phase 8 Workstream 1 complete (2026-04-19, pending PO push). Superset Dashboards. Ships 8 SQL queries (
infra/superset/queries/37_*.sqlthrough44_*.sql) + 1 deploy script (infra/superset/deploy-powerfill.py, 354 LOC, mirrorsdeploy-loan-pnl.pypattern) + 1 dashboard-design doc (docs-site/docs/superset/powerfill-dashboards.md) + sentinel bump tophase-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; matchesdeploy-loan-pnl.py); D-8-2 hybrid 1-hub + 7-detail dashboard structure (matches Phase 7run_idmental 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 mirrors002_CreatePowerFillViews.sqlCTEs minusnote_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 atdocs-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). -
PowerFill Sub-Phase 6d complete (2026-04-19, pending PO push). Verbatim port of
psp_powerfillUE(NVO 13246-19801 =_a13246-16463 +_b16465-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) into011_CreatePowerFillUeProcedure.sql(6,613 total lines). 4 new tables (3pfill_syn_*+pfill_powerfill_log) into010_CreatePowerFillSynTradesSchema.sql; 4 new EF entities (pfill_syn_powerfill_guide_all_rankregistered keyless per F-6d-8 empirical PK probe).PowerFillRunServiceextended with Step 6 (ue) (6 params mirroring conset; 10-min timeout; best-effort post-failure counter hoist);RunSummarygains 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 tophase-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. -
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 includingharness.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+.envgitignored +check_db.py+ 3diagnose_a69*.pyscripts),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 inReportContracts.cs), sentinel bumped tophase-9-validation-ready(drops the-a54-fixedsub-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 identicalSqlException 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: addedRowVerdict.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 — thecomparison_report.md.j2template'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 atpowerfill-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
| # | Item | Status | Blocker |
|---|---|---|---|
| 1 | Pipeline Management spec → approve → implement | Spec in Draft | PO review |
| 2 | Risk Validation Module spec + implement | Not started | Spec not written yet (next spec candidate) |
| 3 | Deploy pssaas-staging to AKS | LIVE | SQL MI firewall rule needed for Superset |
| 4 | React frontend scaffold | Not started | Low priority |
| 5 | Research PowerServer transaction semantics | Not started | Tom's evaluation |
| 6 | Research Odoo API for provisioning | Not started | — |
| 7 | Remaining 8 BestEx pipeline TODOs | Available | — |
| 8 | Jay: loan table customization patterns | Partially answered (143+14) | Follow-up on post-purchase tracking |
| 9 | Greg: review risk deep dive | Not started | Greg's availability |
| 10 | Lisa: V1 feature surface | Not started | — |
| 11 | Synthetic test data for BestEx | Not started | — |
| 12 | Tom: test LLPA plugin against PSX staging | Not started | API key (PSX ops) + staging access |
| 13 | Website content review (Lisa / Greg / Jay) | Drafts ready | Reviewer availability |
| 14 | Re-add Docusaurus full-text search | Blocked | Needs compatible search plugin for pinned Docusaurus/webpack |
| 15 | MIAC SRP evaluation endpoint (Rudy) — design + build | Not started | Pending PO decision on PSX vs PSSaaS location |
| 16 | Superset Phase 2 dashboards (Pipeline Health, Trading, Cost of Hedging, Cross Ratios) | Not started | Phase 1 deployed first |
| 17 | Deploy Phase 1 dashboards to PSX Superset staging | DONE | — |
| 18 | PowerFill Module — Phase 1 (domain model + schema) | Done | — |
| 19 | PowerFill Module — Phase 2 (data access + preflight + views) | Done | — |
| 20 | PowerFill Module — Phase 3 (pre-processing procedures + orchestration) | Done | — |
| 21 | PowerFill Module — Phase 4 (constraint / carry-cost / lockdown CRUD + tenant-configurable preflight thresholds) | Done | Deploy 004+005 on any DB provisioned before 2026-04-16 Phase 4 merge |
| 21b | PowerFill Module — Phase 7 (Reports / Recap Query APIs) | Done | 8 GET endpoints + ADR-025 latest-Complete-wins; F-7-8 / 688-row Cash Trade Slotting pattern; A59-A62 added |
| 21c | PowerFill Module — Phase 8 W1 (Superset Dashboards) | Done | 8 dashboards × 25 charts at PSX Superset IDs 13-20; A63-A64 added; F-8-BR-1 first empirical Backlog-re-read demonstration |
| 21d | PowerFill Module — Phase 8 W2 (React UI) | Done | Greenfield 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. |
| 22 | PowerFill 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. |
| 32 | A62 closure — pfillv_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 scope | Decision 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. |
| 33 | A69 root-cause investigation — sqlcmd-direct UE failure on non-empty post-pool_guide state | Deferred from Phase 9 first-run; Greg/Tom consultation hook | Pin 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. |
| 34 | A70 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 drafting | Phase 10+ playbook needs an explicit "verify PSSaaS-deployed proc bodies are running" step before first PSSaaS run on a new customer DB. |
| 35 | Phase 9 ADR renumbering — RESOLVED in this commit batch | DONE 2026-04-20 | Phase 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. |
| 23 | PS_DemoData schema deployment (001_CreatePowerFillSchema.sql) | UNBLOCKED 2026-04-16 evening | kevin_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). |
| 24 | PS_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. |
| 25 | PS_DemoData procedures deployment (003_CreatePowerFillProcedures.sql) | UNBLOCKED 2026-04-16 evening | DDL 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. |
| 26 | Investigate pfill_syn_* synthetic-trades subsystem (3 tables) | Phase 6 prerequisite | Discovered via PS_DemoData probing 2026-04-16; missing from Phase 1 reverse-engineering; Phase 6 Architect kickoff must include primary-source probe (assumption A28). |
| 27 | Credentials in repo: rotate kevin_pssaas_dev password + scrub from infra/azure/HANDOFF-INFRA-AGENT.md and docs-site/docs/superset/setup-guide.md | Security cleanup | Plaintext credentials currently published on staging Docusaurus. Mitigation: scoped user, sanitized data, but pssaas.staging.powerseller.com/docs/superset/setup-guide is internet-reachable. |
| 28 | OIDC repo secrets configuration (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID) | DONE 2026-04-16 evening | Kevin added secrets; OIDC verified end-to-end at commit 5417d9a (docs deploy) and e90c494 (api deploy). |
| 29 | Preflight default thresholds calibration (Kevin/Jay/Greg) | Awaiting review | Phase 2 plan Open Q #4; Phase 4 makes tenant-configurable |
| 30 | Superset → pss-platform migration (PSX Infra-driven) | DONE 2026-04-19 | Faster 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. |
| 31 | Phase 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-platform → psx-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. |
| 32 | Greg-demo data-richness question | WAITING 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 work | Surfaced 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 Joe — PROMOTED 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
| Document | Path | What It Contains |
|---|---|---|
| CLAUDE.md | CLAUDE.md | Lean session context (read every session) |
| AGENTS.md | AGENTS.md | Agent memory — durable principles, lessons, preferences |
| .cursorrules | .cursorrules | Development rules (specs first, ADRs, conventional commits, PO governance) |
| Website drafts | docs-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 Spec | docs-site/docs/specs/bestex-engine.md | Approved, 50+ requirements, 45 business rules |
| Pipeline Spec | docs-site/docs/specs/pipeline-management.md | Draft, secondary marketing overlay model |
| Pricing Evolution | docs-site/docs/ecosystem/pricing-integration-evolution.md | 3-phase PSX integration (buyer pricing → agency pricing → universal) |
| Xigo Requirements | docs-site/docs/ecosystem/xigo-external-data-requirements.md | External data feeds + SA answers + rate sheet generator design |
| dataQollab Discovery | docs-site/docs/ecosystem/dataqollab-tba-pricing-discovery.md | TBA pricing already available via MBS Access |
| Market Data Retention | docs-site/docs/ecosystem/market-data-retention-spec.md | 10 scheduled snapshots/day + event-driven |
| Value Discovery | docs-site/docs/ecosystem/value-discovery-strategy.md | Go-to-market strategy for Desktop App customers |
| PowerServer Coexistence | docs-site/docs/ecosystem/powerserver-coexistence.md | Desktop App → PowerServer → PSSaaS migration with plugin bridge |
| Plugins Deep Dive | docs-site/docs/legacy/plugins-deep-dive.md | 32 Desktop App plugins analyzed |
| Loan Baseline | docs-site/docs/legacy/loan-table-baseline.md | 143 standard columns, all categorized |
| Product Licensing | docs-site/docs/legacy/product-licensing-modules.md | 5 Desktop App licensed modules |
| MIAC Analysis | docs-site/docs/legacy/miac-srp-workbook-analysis.md | Third Federal MIAC XLSX structure; SRP grids vs loan-level MSR; LLPA parity |
| Superset Designs | docs-site/docs/superset/dashboard-designs.md | BestEx Scorecard + Position Recon layouts, charts, cross-filter specs |
| Superset Setup | docs-site/docs/superset/setup-guide.md | Connection config, dataset creation for PSX Superset admin |
| Superset SQL | infra/superset/queries/ | 15 SQL files (6 report translations + 9 dashboard charts) |
| PowerFill Deep Dive | docs-site/docs/legacy/powerfill-deep-dive.md | Legacy plugin reverse-engineering: 25 files, 17 tables (corrected in Phase 1), 7 procedures, pool action semantics |
| PowerFill Spec | docs-site/docs/specs/powerfill-engine.md | Full module spec: requirements, business rules, data contracts, 10-phase roadmap |
| PowerFill Assumptions | docs-site/docs/specs/powerfill-assumptions-log.md | 68 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 Readiness | docs-site/docs/handoffs/powerfill-a54-fix-greg-demo-readiness.md | Completion 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 Completion | docs-site/docs/handoffs/powerfill-phase-8-w2-completion.md | Completion 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 Kickoff | docs-site/docs/agents/powerfill-phase-9-kickoff.md | Architect 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 Kickoff | docs-site/docs/agents/powerfill-phase-8-5-kickoff.md | Architect 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 UI | src/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.md | Ecosystem-wide discipline: 10 practices, 13 antipatterns, nomination template, signal-based cadence. Current revision v4.1. |
| PSX Relay Stub | docs-site/docs/agents/psx-relay-stub.md | Short block Kevin relays to PSX/MBS Access Collaborator agents so they reference the canonical |
| Agent Roles Overview | docs-site/docs/agents/README.md | Multi-agent structure: Collaborator / Architect / Developer boundaries |
| Collaborator Context | docs-site/docs/agents/collaborator-context.md | Collaborator role definition and operating rules |
| Architect Context | docs-site/docs/agents/architect-context.md | Systems Architect role definition, including Required Delegation Categories |
| Developer Context | docs-site/docs/agents/developer-context.md | Developer role definition (fast subagent, manual relay, or self) |
| Handoff Prompt Templates | docs-site/docs/agents/handoff-prompts.md | Seven templates for role transitions and escalations |
| PowerFill Architect Kickoff | docs-site/docs/agents/powerfill-architect-kickoff.md | Original prompt used to bootstrap the Architect on PowerFill Phase 1 |
| PowerFill Phase 1 Nomination | docs-site/docs/agents/powerfill-phase-1-antipattern-nomination.md | Phase-0 Truth Rot nomination record |
| PowerFill Phase 2 Gate Clarification | docs-site/docs/agents/powerfill-phase-2-gate-clarification.md | Primary-Source Verification Gate scope clarification (v3.1) |
| Delegation Skip Nomination | docs-site/docs/agents/delegation-skip-antipattern-nomination.md | v4 nomination record |
Git State
Main branch. 3 LOCAL commits ahead of origin/main (PO pushes; Architect commits only):
4c3b921(Phase 8.5 W1 atomic): oauth2-proxy + Keycloak realm/client setup; cross-project-relay request to PSX Infra; W1 checkpoint Architect Reporta16e4a7(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- (pending Architect commit, this session): PSX Infra response acknowledgment + PSSaaS-side fixes (realm rename
pss-platform→psx-stagingin oauth2-proxy.cfg + services.yaml; Superset Secret reference rename + in-cluster URL switch;oauth2-proxy-secrets.yaml.examplereframing; 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)
a16e4a72026-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)4c3b9212026-04-20 (LOCAL; pending push) — Phase 8.5 W1 atomic commit (oauth2-proxy + ingress + GHA + cross-project-relay request + W1 checkpoint report)f1413a82026-04-20 — Phase 8.5 kickoff drafted + session-handoff aligned31b5d592026-04-19 — bank PSX Collab close-out — adopt "Writer-Time vs Reader-Time Truth Divergence" family heading9a83b922026-04-20 — backlog #30/#31 + A64/A68 platform-tailwinds (PO direction during post-W2-deploy session)8dba7b42026-04-20 — Path γ for F-W2-PSD-1 (Tenants__ps-demodata__ConnectionStringenv var on staging API + A68 banked)d4d294e2026-04-19 — F-W2-PSD-1 fix (PS608 removed from tenant dropdown + tenant ID →ps-demodata+ case-insensitiveTenantRegistry)1de964d2026-04-19 — Phase 8 W2 docs (ADR-026 + spec + A67 + completion report + devlog + handoff)9be1b8e2026-04-19 — Phase 8 W2 infra (frontend Deployment + Service + ingress/apppath + GHA workflow)10f98912026-04-19 — Phase 8 W2 React UI scaffold (~50 source files undersrc/frontend/)f4531ae2026-04-19 — W2 kickoff body scrub (post-4b08b51 follow-up)4b08b512026-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)
- Specs before code. No development without a specification.
- Conventional commits.
feat:,fix:,docs:,chore:,test:,refactor: - Never push. Only the Product Owner pushes.
- Post-completion checklist. Devlog, glossary, ADRs, Arc42, specs — check all before committing.
decimalfor money. Neverfloatordoublein C#.- Tenant isolation. Every query scoped to authenticated tenant's database.
- Read CLAUDE.md and this handoff at the start of every resumed session.