Compare commits

...
5 Commits
4 changed files with 208 additions and 28 deletions
+32 -1
View File
@@ -1,5 +1,36 @@
import LoginForm from "@/components/login-form"; import LoginForm from "@/components/login-form";
export default function LoginPage() { export default function LoginPage() {
return <LoginForm />; return (
<main className="mx-auto min-h-[calc(100vh-57px)] max-w-[1200px] px-6 py-16">
<div className="mx-auto flex flex-col gap-y-8 md:grid md:grid-cols-[minmax(0,1fr)_420px] md:gap-x-8 md:items-start">
<section>
<h1 className="text-3xl font-bold tracking-tight text-teal-700">Confidence Engine</h1>
<div className="mt-4 space-y-4 text-base leading-relaxed text-gray-700">
<h2 className="text-xl font-semibold tracking-tight text-gray-900">Get clearer about what{'\''}s really going on.</h2>
<p>Confidence Engine helps you work through situations that feel uncertain, complicated or difficult to act on.</p>
<p>Describe the situation in your own words. Confidence Engine will help reconstruct what is known, what may be happening, and what is still unclear then let you decide what to explore further.</p>
<p className="text-gray-600">It doesn{'\''}t try to make the decision for you. The aim is to help you reach a clearer understanding so you can decide what to do with more confidence.</p>
</div>
</section>
<section className="md:col-start-2 md:w-full">
<LoginForm />
</section>
<section className="space-y-4">
<h2 className="text-sm font-semibold uppercase tracking-[.18em] text-teal-700/70">How it works</h2>
<ol className="space-y-3 text-base leading-relaxed text-gray-700">
<li><strong>1. Describe your situation</strong><br/><span className="text-gray-600">As much or as little as you currently know.</span></li>
<li><strong>2. Explore what{'\''}s unclear</strong><br/><span className="text-gray-600">Answer the questions that feel useful; skip the ones that don{'\''}t.</span></li>
<li><strong>3. Build your Current Understanding</strong><br/><span className="text-gray-600">Your picture of the situation develops as you learn more.</span></li>
<li><strong>4. Stop when you have enough</strong><br/><span className="text-gray-600">You don{'\''}t have to answer everything. Your investigation is saved so you can return later.</span></li>
</ol>
<p className="text-sm italic text-gray-500">Try it with something real.<br/>A decision you{'\''}re unsure about. A problem that doesn{'\''}t quite make sense. A situation where you feel you may be missing something.</p>
</section>
</div>
</main>
);
} }
+11 -4
View File
@@ -25,8 +25,8 @@ export default function LoginForm() {
} }
return ( return (
<main className="mx-auto flex min-h-[calc(100vh-57px)] max-w-[640px] items-center px-6 py-16"> <section className="w-full shrink-0 space-y-6">
<section className="w-full rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 py-9 shadow-sm"> <div className="rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 py-9 shadow-sm">
<p className="mb-3 text-[11px] font-bold uppercase tracking-[.18em] text-teal-700/70">Welcome</p> <p className="mb-3 text-[11px] font-bold uppercase tracking-[.18em] text-teal-700/70">Welcome</p>
<h1 className="text-3xl font-bold tracking-tight">Confidence Engine</h1> <h1 className="text-3xl font-bold tracking-tight">Confidence Engine</h1>
<p className="mt-3 text-sm leading-relaxed text-gray-600">Enter your email and we will send you a secure link to continue.</p> <p className="mt-3 text-sm leading-relaxed text-gray-600">Enter your email and we will send you a secure link to continue.</p>
@@ -39,7 +39,14 @@ export default function LoginForm() {
</form> </form>
{status === "sent" && <p className="mt-5 text-sm text-green-700" role="status">Check your email for your magic link.</p>} {status === "sent" && <p className="mt-5 text-sm text-green-700" role="status">Check your email for your magic link.</p>}
{error && <p className="mt-5 text-sm text-red-700" role="alert">{error}</p>} {error && <p className="mt-5 text-sm text-red-700" role="alert">{error}</p>}
</section> </div>
</main>
<div className="pt-3 space-y-3">
<p className="text-sm font-medium text-gray-700">Sign in to continue</p>
<p className="text-sm leading-relaxed text-gray-600">Enter your email and we{'\''}ll send you a secure sign-in link.</p>
</div>
<p className="text-xs text-gray-500">Your investigations are private to your account and saved so you can return to them later.</p>
</section>
); );
} }
+123 -12
View File
@@ -3,19 +3,107 @@
> **Role:** Concise operational snapshot for resuming work today. Not a historical diary. > **Role:** Concise operational snapshot for resuming work today. Not a historical diary.
> The design evolution archive index at `docs/design-evolution/README.md` provides progressive loading of experiment history; load the relevant chapter only when a specific historical question requires it. > The design evolution archive index at `docs/design-evolution/README.md` provides progressive loading of experiment history; load the relevant chapter only when a specific historical question requires it.
## v0.62d production Docker packaging established ## v0.62d production Docker packaging — LIVE PROVEN
- `Dockerfile` — minimal multi-stage Alpine build (Node 22), Next.js standalone output mode - `Dockerfile` — minimal multi-stage Alpine build (Node 22), Next.js standalone output mode
- `.dockerignore` — excludes dev artefacts, secrets, docs from build context - `.dockerignore` — excludes dev artefacts, secrets, docs from build context
- `next.config.mjs` — added `output: 'standalone'` (required for lean production container) - `next.config.mjs` — added `output: 'standalone'` (required for lean production container)
- `.env.example` — reorganized: Supabase → Ollama → Mock sections; Ollama vars now tracked as deployment-relevant - `.env.example` — reorganized: Supabase → Ollama → Mock sections; Ollama vars now tracked as deployment-relevant
- **npm production build: PASS** ✓ - **npm production build: PASS** ✓
- **Docker image build: BLOCKED** — no Docker runtime on development machine (apparatus limitation, not product defect) - **Docker image build on CT 112: PROVEN** — production Docker image builds successfully on CT 112, standalone Next.js container starts successfully.
- Production container starts / `/api/health` smoke test: pending Docker runtime availability - Production container `/api/health`: **PROVEN**`{"healthy":true}`, no private Ollama endpoint / model name / raw internal error exposed.
- No persistent application volume required - No persistent application volume required.
- Supabase remains external, Ollama remains private and server-reachable - Supabase remains external, Ollama remains private and server-reachable from the deployment host.
- Public `NEXT_PUBLIC_*` variables may require build-time injection via `--build-arg` as established by the implementation (baked into browser bundle) - Public `NEXT_PUBLIC_*` variables may require build-time injection via `--build-arg` as established by the implementation (baked into browser bundle).
- **No deployment performed yet** - **Deployment: LIVE PROVEN** — manual Jenkins pipeline succeeded end-to-end (SHA-tagged image, container replaced, health check passed).
### v0.62d External Deployment (LIVE)
Confidence Engine is externally reachable at **https://confidence.rdbcloud.co.uk**.
Production topology:
```
Internet → HTTPS → Nginx Proxy Manager → CT 112 / Confidence Engine Docker container
```
CT 112 deployment details:
```
hostname: confidence-engine
LAN address: 192.168.68.73
repo: /opt/confidence-engine
container: confidence-engine
port: 3000
```
Docker-in-LXC has been proven. Docker image builds successfully on CT 112.
### v0.62d Magic-Link Login (LIVE)
External magic-link login has been proven through the deployed application at `https://confidence.rdbcloud.co.uk`. The reverse-proxy callback-origin defect was corrected; successful login now returns to the external Confidence Engine Portfolio rather than `0.0.0.0:3000`.
Auth email branding configured on external Supabase infrastructure (outside this repository):
- Confidence Engine sender name / subject / branded HTML body
- SPF PASS, DKIM PASS, DMARC PASS — recipient-side confirmed
- Missing original Message-ID / junk-folder observation remains a non-blocking external mail-deliverability note
### v0.62d Multi-user Boundary (LIVE)
Application-level isolation proven on deployed instance:
```
User A sees User A investigations
User B does not see User A investigations
```
### v0.62d Real Deployed Product Journey (LIVE)
Manually proved through the externally deployed application:
```
authenticate → Portfolio → create new investigation → reason through Qwen
→ server persistence → return to Portfolio → leave/return → investigation restored
```
Server-backed persistence remains authoritative. Legacy localStorage investigations remain ignored.
### v0.62d Manual Jenkins Deployment Pipeline (LIVE PROVEN)
Manual end-to-end pipeline proven:
```
manual Jenkins Build with Parameters → GIT_REF accepted
→ remote ref resolved to immutable SHA → Jenkins SSH credential bound
→ SSH to CT 112 → deployment script executed → exact SHA fetched/checked out
→ Docker image built and tagged by SHA → existing CE container replaced
→ /api/health polled → healthy response observed → DEPLOYMENT SUCCEEDED
```
Pipeline design:
- Manual trigger, runtime-selectable `GIT_REF`, immutable SHA deployment
- CT 112 as Docker build/runtime host, target-owned `/opt/confidence-engine/deploy.env`
- SHA-tagged Docker images, health-gated success, bounded rollback support
- No Docker registry, no automatic webhook deploy
**Path status:** success path = LIVE PROVEN. rollback path = IMPLEMENTED, NOT LIVE PROVEN.
Jenkins SCM branch used to load the Jenkinsfile is conceptually separate from the `GIT_REF` chosen for deployment.
## v0.63 First-Time Unauthenticated Product Framing
- login page now explains product purpose and investigation flow to first-time visitors without prior explanation
- user judgement/choice explicitly preserved ("It doesn't try to make the decision for you")
- existing magic-link authentication unchanged
- no broader onboarding/tutorial system introduced
### Mobile-first sign-in order (responsive layout fix)
- v0.63f corrected mobile reading order: proposition → sign-in card → supporting explanation
- CSS Grid with responsive column placement replaces original flexbox; three DOM sections ensure correct mobile stacking without duplicating content
- desktop two-column presentation (explanation left / sign-in right) preserved unchanged at `md` breakpoint and above
## CURRENT MVP DIRECTION ## CURRENT MVP DIRECTION
@@ -75,9 +163,10 @@ Does the complete investigation process leave real people materially clearer abo
- The full apply-proposal owner suite remains known-red in independent pre-existing 60B.43 tests, so the changed Done-for-now boundary was verified through exact isolated owner tests. Zero live calls occurred during closeout. Next boundary: reuse the existing investigation and click Done for now once, observing cases/update and subsequent synthesis. - The full apply-proposal owner suite remains known-red in independent pre-existing 60B.43 tests, so the changed Done-for-now boundary was verified through exact isolated owner tests. Zero live calls occurred during closeout. Next boundary: reuse the existing investigation and click Done for now once, observing cases/update and subsequent synthesis.
- Live UI proved Done for now briefly clarified the question, then server graph replacement reopened it: the client sends `preDoneGraph`, and the server previously had no deterministic closure owner. Episode-mode update now adds the selected `targetNodeId` to `resolvedNodeIds` only after successful semantic application; semantic no-ops and meaningful mutations remain valid, while failed episodes do not resolve the target and ordinary updates are unchanged. Zero live calls occurred during implementation. Next boundary: one live Done-for-now check on the existing investigation. - Live UI proved Done for now briefly clarified the question, then server graph replacement reopened it: the client sends `preDoneGraph`, and the server previously had no deterministic closure owner. Episode-mode update now adds the selected `targetNodeId` to `resolvedNodeIds` only after successful semantic application; semantic no-ops and meaningful mutations remain valid, while failed episodes do not resolve the target and ordinary updates are unchanged. Zero live calls occurred during implementation. Next boundary: one live Done-for-now check on the existing investigation.
## Deployment automation (new) ## Deployment automation (LIVE PROVEN)
Manual Jenkins deployment pipeline established, version-controlled, and LIVE PROVEN end-to-end.
- Manual Jenkins deployment pipeline established and version-controlled.
- `Jenkinsfile` in repository root — Declarative Pipeline, three stages: Resolve → Deploy → Verify/result. - `Jenkinsfile` in repository root — Declarative Pipeline, three stages: Resolve → Deploy → Verify/result.
- `scripts/deploy-production.sh` — executes on CT 112; validates SHA, fetches Git ref, checks out exact commit, builds Docker image tagged by SHA, replaces container, polls `/api/health`, one-step rollback to prior image on failure. - `scripts/deploy-production.sh` — executes on CT 112; validates SHA, fetches Git ref, checks out exact commit, builds Docker image tagged by SHA, replaces container, polls `/api/health`, one-step rollback to prior image on failure.
- `deploy.env.example` — example of required runtime/build environment file (NOT tracked). - `deploy.env.example` — example of required runtime/build environment file (NOT tracked).
@@ -85,13 +174,35 @@ Does the complete investigation process leave real people materially clearer abo
- `GIT_REF` is runtime-selectable (Jenkins parameter); resolves to immutable SHA before deployment. - `GIT_REF` is runtime-selectable (Jenkins parameter); resolves to immutable SHA before deployment.
- No Docker registry introduced. SHA-tagged images retained for rollback support. - No Docker registry introduced. SHA-tagged images retained for rollback support.
- Jenkins job remains manually triggered — no automatic webhook deployment. - Jenkins job remains manually triggered — no automatic webhook deployment.
- No product behaviour changed. - No product behaviour changed by deployment automation.
**Success path: LIVE PROVEN.** **Rollback path: IMPLEMENTED, NOT LIVE PROVEN.**
## Repository checkpoint ## Repository checkpoint
- **Branch:** `feature/product-platform-foundation-v0.62` - **Branch:** `feature/product-platform-foundation-v0.62`
- **HEAD:** `6dd447e` — feat(confidence-engine): add authenticated investigation persistence - **HEAD:** *(checkpoint commit — see git log for actual SHA)*
- **Working tree:** dirty with completed v0.62c cutover (server-authoritative persistence, async seam, 404→null correction) - **Working tree:** clean
## Architectural Conclusion
**The original v0.62 product-platform objective is achieved:**
- Authenticated identity (magic-link via self-hosted Supabase)
- Authenticated reasoning APIs (private Ollama/Qwen, server-reachable)
- User-owned server persistence (Supabase `investigations`, RLS-scoped)
- Multi-user application behaviour (application-level isolation proven)
- Portable Docker runtime (Docker-in-LXC on CT 112)
- External HTTPS deployment (Nginx Proxy Manager → CE container)
- External magic-link authentication (callback fix, email branding proven)
- Manual one-touch Jenkins deployment (SHA-tagged, health-gated)
**The following are NOT required and NOT justified before testing:**
- Legacy localStorage migration — not required. Four development/test investigations will not be migrated; legacy data remains invisible to normal product flow.
- Additional SaaS/platform machinery — not justified before real user testing.
> **Platform/deployment foundation work is complete enough to disappear into the background. The next Confidence Engine work should return to product/reasoning/user-learning priorities rather than continuing infrastructure expansion unless a real operational failure demands it.**
## Persistence ## Persistence
+42 -11
View File
@@ -1,18 +1,34 @@
# Current Project State — Confidence Engine # Current Project State — Confidence Engine
## v0.62d Production Docker Packaging ## v0.62d Production Docker Packaging — LIVE PROVEN
- `Dockerfile` created: multi-stage Alpine build (Node 22), Next.js standalone output, configurable port 3000, health-check boundary via `/api/health` - `Dockerfile` created: multi-stage Alpine build (Node 22), Next.js standalone output, configurable port 3000, health-check boundary via `/api/health`
- `.dockerignore` created: excludes `node_modules`, `.next`, secrets (`env.*.local`), docs, IDE, OS artefacts - `.dockerignore` created: excludes `node_modules`, `.next`, secrets (`env.*.local`), docs, IDE, OS artefacts
- `next.config.mjs`: added `output: 'standalone'` for lean production container (only config change required) - `next.config.mjs`: added `output: 'standalone'` for lean production container (only config change required)
- `.env.example`: reorganized; Ollama variables now tracked as deployment-relevant env vars - `.env.example`: reorganized; Ollama variables now tracked as deployment-relevant env vars
- npm production build: PASS ✓ - npm production build: PASS ✓
- Docker image build: blocked — no Docker runtime on development machine (apparatus limitation, not product defect) - Docker image build on CT 112: **PROVEN** — builds successfully, standalone container starts successfully.
- Production container start / `/api/health` smoke test: pending Docker availability - Production container `/api/health`: **PROVEN**`{"healthy":true}`, no private Ollama model name / raw internal error exposed.
- No persistent application volume required - No persistent application volume required.
- Supabase remains external; Ollama remains private and server-reachable - Supabase remains external; Ollama remains private and server-reachable from deployment host.
- Public `NEXT_PUBLIC_*` variables may require build-time injection via `--build-arg` (baked into browser bundle) - Public `NEXT_PUBLIC_*` variables may require build-time injection via `--build-arg` (baked into browser bundle).
- **No deployment performed** - **Deployment: LIVE PROVEN** — manual Jenkins pipeline succeeded end-to-end.
### External Deployment (LIVE)
Confidence Engine is externally reachable at **https://confidence.rdbcloud.co.uk**.
Topology: Internet → HTTPS → Nginx Proxy Manager → CT 112 / Confidence Engine Docker container.
CT 112: hostname `confidence-engine`, LAN `192.168.68.73`, repo `/opt/confidence-engine`, container `confidence-engine`, port `3000`.
### External Magic-Link Login (LIVE)
Magic-link authentication proven through deployed instance. Callback-origin defect corrected; login returns to external portfolio rather than `0.0.0.0:3000`. Email branding configured on external Supabase (sender name, subject, branded HTML body). SPF/DKIM/DMARC confirmed recipient-side.
### Multi-user Boundary (LIVE)
Application-level isolation proven on deployed instance — User A does not see User B investigations and vice versa.
> Created by Experiment 27. This document is the starting point for any fresh session working on the Confidence Engine. Read this first, then follow the routing table below to task-specific references. > Created by Experiment 27. This document is the starting point for any fresh session working on the Confidence Engine. Read this first, then follow the routing table below to task-specific references.
@@ -188,9 +204,9 @@ First document to read: **`docs/current-handoff.md`** (methodology continuity +
Implementation status last checked against source: Experiment 43 + v0.61 apparatus (tsx helper, reconstruction-only seam, focused-deconstruction schema fix). Multi-investigation architecture verified at v0.60g2+ and structurally complete. The current-state document was verified as accurate by focused code inspection of API routes, orchestrator imports/calls, and cross-module traces for all passive classifiers. No corrections were required. Implementation status last checked against source: Experiment 43 + v0.61 apparatus (tsx helper, reconstruction-only seam, focused-deconstruction schema fix). Multi-investigation architecture verified at v0.60g2+ and structurally complete. The current-state document was verified as accurate by focused code inspection of API routes, orchestrator imports/calls, and cross-module traces for all passive classifiers. No corrections were required.
## Deployment Automation ## Deployment Automation — LIVE PROVEN
A manual Jenkins deployment pipeline has been established and is now repository-owned. A manual Jenkins deployment pipeline has been established, version-controlled, and LIVE PROVEN end-to-end.
- **Jenkinsfile** (root) — Declarative Pipeline with three stages: `Resolve``Deploy``Verify/result`. - **Jenkinsfile** (root) — Declarative Pipeline with three stages: `Resolve``Deploy``Verify/result`.
- **Parameter:** `GIT_REF` (string) — user-supplied Git ref (branch, tag, or SHA). Blank value fails clearly. - **Parameter:** `GIT_REF` (string) — user-supplied Git ref (branch, tag, or SHA). Blank value fails clearly.
@@ -199,8 +215,23 @@ A manual Jenkins deployment pipeline has been established and is now repository-
- **Docker image:** tagged `confidence-engine:<sha>`, built on CT 112, no registry required. - **Docker image:** tagged `confidence-engine:<sha>`, built on CT 112, no registry required.
- **Environment:** production values in `/opt/confidence-engine/deploy.env` on CT 112 (not in Git). `deploy.env.example` provided as reference. - **Environment:** production values in `/opt/confidence-engine/deploy.env` on CT 112 (not in Git). `deploy.env.example` provided as reference.
- **Health check:** polls `http://127.0.0.1:3000/api/health`; requires `{"healthy":true}` within 60s. - **Health check:** polls `http://127.0.0.1:3000/api/health`; requires `{"healthy":true}` within 60s.
- **Rollback:** one-step rollback to the previous container image on failure (if available). - **Rollback:** one-step rollback to the previous container image on failure (if available). **IMPLEMENTED, NOT LIVE PROVEN.**
- **Not configured in this increment:** Jenkins job, deploy.env values, SSH credential, first deployment run. - **Jenkins job:** configured and operational. First successful deployment recorded with explicit "DEPLOYMENT SUCCEEDED" output.
- **Jenkins SCM branch** used to load the Jenkinsfile is conceptually separate from the `GIT_REF` chosen for deployment.
### Pipeline design notes
- Manual trigger only — no automatic webhook deploy.
- No Docker registry introduced; SHA-tagged images retained on CT 112 for rollback support.
- No product behaviour changed by deployment automation.
## 9. First-Time Unauthenticated Landing/Login Framing
- login page now explains product purpose and investigation flow to first-time visitors without prior explanation
- user judgement/choice explicitly preserved ("It doesn't try to make the decision for you")
- existing magic-link authentication unchanged
- no broader onboarding/tutorial system introduced
- verified via Playwright semantic locators (heading, text content, form controls) and responsive viewport
## 10. Post-v0.8 Methodology Learning ## 10. Post-v0.8 Methodology Learning