# Learnitive 2.0 — Hotfix32 Autonomous Continuation Prompt

## Objective

Continue Learnitive 2.0 autonomously from the Hotfix32 source state. Do not redo completed implementation. The immediate task is authoritative staging acceptance of the deep-audited legacy Learn-schema compatibility repair.

## Protected boundaries

Deployment target only:

- `https://os.learnitive.com`
- `/var/www/os.learnitive.com`
- `/var/www/os.learnitive.com/public_html`
- `/etc/learnitive`

Do not modify production `learnitive.com` / `www.learnitive.com`, `texise.com` / `www.texise.com`, `/etc/texise/*`, TeXise vhosts or TeXise services.

Canonical staging ports: API 4210, collaboration 4211, Redis 7387, Console Gateway 9887, Universal Runner 9890.

## Latest authoritative staging result

Hotfix31 passed canonical ports, frozen lock/runtime/R12 preflights, unified execution image, real runner/Docker bind checks, production pnpm/Vite build, trusted-server/Console dependency preflights and the Learn media systemd sandbox verifier.

It then failed during the SaaS migration/Learn integrity preflight, before main service activation:

`[Learnitive SaaS preflight error] STARTUP_ERROR: Failed to restore canonical Learn course python-fundamentals: Field 'public_id' doesn't have a default value`

This is the hidden legacy constraint Hotfix30's `INSERT IGNORE` had masked. Do not remove universal templates: staging already proved the universal template library healthy and the current failure occurs before template validation.

## Hotfix32 correction

The deep audit found that merely restoring missing canonical columns is insufficient on a long-lived upgraded database. Extra legacy `NOT NULL`/no-default columns can still make modern inserts impossible, and index names can collide while describing different keys.

Hotfix32 therefore changes `server/saas-migrations.mjs` so that it:

- introspects full live Learn column metadata on every canonical Learn table;
- detects extra legacy mandatory columns that block canonical writes;
- explicitly relaxes retired compatible `public_id`/`uuid` identity columns to nullable while preserving existing data and indexes;
- fails closed on unknown mandatory legacy columns instead of guessing a destructive repair;
- verifies actual index columns and uniqueness, not index names alone;
- preserves conflicting legacy indexes and creates canonical fallback names when required;
- restores canonical unique keys for course/module/lesson slugs and media storage keys after duplicate checks;
- verifies the complete canonical course → module → lesson graph, not only course slugs;
- transactionally restores a missing course with its canonical dependency graph;
- repairs missing modules/lessons below an already-existing canonical course;
- keeps legacy compatibility repair separate from migration structural state so a relaxed `public_id` cannot suppress a genuinely missing migration's data replay.

`server/saas-preflight.mjs` now emits:

- `learnLegacyColumnsRelaxed=<count>`;
- `learnSeedMissingBefore=<count>` / `learnSeedMissingAfter=<count>`;
- `learnSeedGraphMissingBefore=<count>` / `learnSeedGraphMissingAfter=<count>`.

The required staging invariant is:

`learnSeedMissingAfter=0; learnSeedGraphMissingAfter=0`

The exact before-counts and number of relaxed legacy columns depend on the live DB.

## Verification completed

- supported server/static suite: **360/360 PASS**;
- project-runtime strip-types suite: **10/10 PASS**;
- frozen pnpm lock sync PASS: 69 importers / 1581 package records / 1583 snapshots / 1171 reachable snapshots;
- trusted runtime manifest PASS: 9 production imports;
- R12 namespace/static preview/full release contract PASS;
- brand-reference audit PASS: 0 violations across 9810 classified references;
- branding/provenance audit PASS: 708 production-facing text files;
- active brand asset regression: 2/2 PASS;
- staging/root installer shell syntax PASS;
- changed server/audit/test syntax PASS;
- Apache configtest: Syntax OK.

Regression coverage includes the exact `public_id` staging failure, the same blocker on other Learn tables, unsupported legacy blockers, index-name collisions, missing canonical unique keys, duplicate detection, interrupted seed graphs and migration replay ordering.

## Next staging acceptance sequence

1. Deploy Hotfix32 to `os.learnitive.com` only and rerun the installer from the beginning.
2. Confirm SaaS preflight gets past `learn_courses.public_id` and reports `learnSeedMissingAfter=0` plus `learnSeedGraphMissingAfter=0`.
3. Confirm Redis, Universal Runner, Console Gateway and main API become healthy.
4. Confirm all 69 universal templates validate with `failedBuiltins=0`; do not prune healthy templates.
5. Confirm seeded Learn validation reaches every canonical course and interactive exercise.
6. Continue Node/Python/C++ queue smoke and fairness/result isolation.
7. Continue LaTeX API → Redis → Universal Runner smoke, PDF and fallback behavior.
8. Verify React JS/TS, TypeScript/Vite, Vue and Svelte Web Preview and error overlay.
9. Verify Markdown visual/Bangle workflow.
10. Verify Learn uploaded/YouTube/Wistia media, captions/posters, solution gating and Free/Pro entitlements.
11. Verify public HTTPS `/projects`, favicon, fonts and SNI routes.
12. If staging finds another defect, patch the smallest correct source change, add a regression for the exact live shape, rerun supported tests/audits and package the next non-overwriting hotfix.

## Autonomous execution rule

Execute continuously using Execute -> Verify -> Diagnose -> Fix -> Verify again -> Continue. Do not ask for routine confirmation. Ask only when an external credential/permission is genuinely unavailable or an irreversible high-impact action cannot be inferred safely. Maintain the exact current state in durable docs before handoff.

Continue autonomously from this exact state. Do not restart completed phases. Do not ask for confirmation. Execute all remaining phases sequentially, verify each phase, fix problems, and continue until the project is complete. If this chat again approaches its context limit, generate another complete continuation prompt for the next chat before stopping.
