PS Portal — Locked Module Contract for Phase B (16-Agent Rebuild)
This MR adds portal-contract.json — the single source of truth that all 16 Phase-B module agents will read before building their slice of the portal. No module agent re-reads claude.md; they work from this contract only.
What's in the contract
-
79 API endpoints (28 already implemented in server.js v2.0.0; 51 planned — each flagged
"status": "implemented"|"planned") - 14 MongoDB collections with full JSON Schema fragments + index definitions
- 5 Postgres tables (sessions, torch_leaderboard_cache, calendar_events, calendar_rsvp, n8n_workflows)
- Redis key patterns (sessions, Torch daily caps, socket rooms, rate limits)
- 47 Torch scoring rules — one entry per action per module, with tier, pts, dailyCap, and label
- 16 module entries — humanName, htmlFile, usesEndpoints, usesCollections, usesRedisKeys, fireTorchActions, dependencies
- Hard constraints (no AI/LLM, vanilla HTML/CSS/JS only, Torch message shape frozen, JWT-in-Redis auth, Mongo/PG data split)
- File storage spec (volume layout, subfolder structure, naming pattern, hash requirements)
Open questions needing Ed's call before Phase B fires
| ID | Topic |
|---|---|
| OQ-01 | JWT secret rotation policy — static env var or dual-key grace-window? |
| OQ-02 | draw.io banner copy — only exists in claude.md; not yet in any portal-src file |
| OQ-03 | Voice tour — live Web Speech API vs pre-recorded MP3s? Spec says stored audio but live synth is data-safe |
| OQ-04 | Torch anti-gaming cap enforcement approach — Redis counters in recordTorch()? |
| OQ-05 | Cross-instance sync — shared remote MongoDB or per-user instances? |
| OQ-06 | Calendar storage contradiction — Postgres tables AND Mongo collection both defined; pick one |
| OQ-07 | PS Reach reach_requests collection missing from mongo init schema |
| OQ-08 | 6 implemented roles vs 7 spec'd roles — confirm canonical role list |
| OQ-09 | Anti-gaming caps currently unenforced server-side — confirm fix priority |
| OQ-10 | POST /api/notes awards +5 for private notes too — should be public/client only |
| OQ-11 | Live fshost (.23) SSH was denied during contract generation — confirm deployed server.js = v2.0.0 |
| OQ-12 | Only ps_ingest_module.html exists in portal-src; index.html shell + 15 other modules not yet built |
How to review
- Check
portal-contract.jsonis valid JSON (it is —python3 -m json.toolpasses) - Scan
modules{}keys — confirm all 16 are present and theirhtmlFilenames match your naming convention - Review
openQuestionsarray and make calls on OQ-01 through OQ-12 - Merge → Phase B agents spawn
Hard constraints in the contract (verbatim)
- No AI/LLM/Opus/Anthropic API connectivity anywhere in the portal — client data sensitivity policy
- Vanilla HTML/CSS/JS — no React, no build step, no bundler
- All inter-module communication via
window.parent.postMessage(...)per the Torch event spec - Auth = JWT in Redis-backed sessions. Phase B agents do not invent new auth mechanisms.
- MongoDB is the source of truth for documents/notes/reports/news/ask/collab/files; Postgres is sessions + Torch leaderboard cache + calendar