Commit Graph
36 Commits
Author SHA1 Message Date
Lucas WintherandClaude Opus 5.5 d8d62696da merge: learner
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 14:40:29 +01:00
Lucas WintherandClaude Opus 5.5 0da35ec6f8 fix(learner): remove the SPA proxy; CSP as a meta tag in index.html (ruling R16)
The proxy, its internal server, Unix socket and NO_PROXY changes are gone; main.ts serves the HTML
import directly again. apps/web/index.html carries the SPA policy as <meta http-equiv=CSP> ahead of every
script (script-src 'self' plus the hash of Bun's dev-server helper, no unsafe-inline/eval; no
frame-ancestors, which meta cannot carry). Dev HMR connects under it. The runner frame keeps its header CSP.

Tests: the served index.html (prod and dev, in a subprocess) has the meta policy and every inline script
is hash-covered; the XSS browser test fails with the sanitizer disabled and passes with it, and the meta
CSP alone blocks unsanitized handlers (with a no-CSP control); no source assigns proxy env vars, and the
feature leaves them untouched at runtime. Contract request 5 asks core for frame-ancestors/X-Frame-Options.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 14:38:04 +01:00
Lucas WintherandClaude Opus 5.5 213f2247b4 fix(learner): SPA proxy forwards no credentials and never goes through HTTP_PROXY
spaWithCsp proxies GET and HEAD only (405 otherwise, no body buffering) and forwards only accept,
if-none-match, if-modified-since and range. The internal server listens on a Unix socket in a private
0700 temp dir. Bun 1.3.14 ignores proxy: false for this hop, and over a socket with a proxy set it sends
an absolute-form target that breaks asset routing, so localhost, 127.0.0.1 and ::1 are appended to
NO_PROXY/no_proxy (existing entries kept). accept-encoding is no longer forced; fetch decompresses and
the encoding headers are dropped.

Test: in a subprocess with HTTP(S)_PROXY and ALL_PROXY set to a dead proxy, the SPA and an asset load
with the CSP, POST gets 405, and the upstream sees no Cookie, Authorization or X-Forwarded-For.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 14:27:56 +01:00
Lucas WintherandClaude Opus 5.5 c7b9e1f98e fix(learner): review round 1: sanitize-html, sandboxed runner frame, one visibility rule, no Tab capture
C1: lesson HTML goes through a sanitize-html allowlist on the fully rendered output (no on* attributes, no
style, no svg/math/iframe/object/embed/form; URLs limited to http(s), mailto, relative and anchors). Raw tags
outside the allowlist are escaped as text. The SPA document is served with a CSP (script-src 'self', no inline
script) through spaWithCsp in main.ts; contract request §5 asks core to own it.

C2: exercises run in <iframe sandbox="allow-scripts"> (opaque origin, no cookies) loaded from
/api/learner/runner-frame, whose CSP allows only its own script (by hash) and blob: workers, and connect-src
'none'. postMessage only, both sides check event.source; the timeout removes the frame. The worker stubs now
also cover Worker, SharedWorker and caches.

I1: learner visibility calls core canView with per-course authorship only, like /api/media (contract request §6).
I2: Tab and Shift+Tab move focus; Enter keeps the previous line's indentation.

Tests: XSS unit cases, headless-Chrome checks for the exploit lesson and for fetch, import, Cache.add, nested
Worker, img, EventSource, WebSocket, XHR and sendBeacon from learner and test code (plus a negative control),
visibility on both dialects, SPA and runner-frame CSP headers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 05:20:43 +01:00
Lucas WintherandClaude Opus 5.5 061ae7a2d9 feat(learner): search results show lesson matches cleanly; contract notes for the browser entry and LessonView; plan marked done
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 04:54:53 +01:00
Lucas WintherandClaude Opus 5.5 89c51f013d feat(learner): web shell, library, lesson views (LessonView), decks, code files, exercises, notes, account and admin pages
Tasks 10-12 of the WP-A plan in one commit (the route modules import each other):
- header extras portalled into the Phase 0 header: course switcher, search, Reading/Work, account
- course frame with outline sidebar (mobile overlay, Escape closes), progress, gating locks
- library: featured course, continue row, New and collection rows, course list, filters, search
- LessonView: text (track switcher, folds, ordered hint tiers), video (resume, done near the end,
  timestamp notes, transcript), companion decks rendered with pdf.js (thumbs, arrows, fullscreen,
  per-slide notes), code files (tree, tabs, copy, zip, command), exercises (Web Worker runner or
  local command with optional pasted evidence), floating action bar
- notes list, account (email/password, providers, SSO by email) and owner admin pages
- pdf.js worker served from /api/learner/pdf.worker.mjs
- browser entry @stc/feature-learner/web (the package index also carries the server half)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 04:53:36 +01:00
Lucas WintherandClaude Opus 5.5 99c0e4929f feat(learner): lesson markdown pipeline with track variants, folds, hint tiers and safe HTML
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:29:14 +01:00
Lucas WintherandClaude Opus 5.5 9ff5862382 feat(learner): JS/TS exercise runner in a Web Worker with timeout and network blocked
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:26:32 +01:00
Lucas WintherandClaude Opus 5.5 752e44696f fix(learner): zip buffer types
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:25:30 +01:00
Lucas WintherandClaude Opus 5.5 34826762a8 feat(learner): section code listing and zip download
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:25:18 +01:00
Lucas WintherandClaude Opus 5.5 478ebeb255 fix(learner): narrow lesson target result for the type checker
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:24:28 +01:00
Lucas WintherandClaude Opus 5.5 96c147e3a2 feat(learner): progress, notes and exercise attempt API
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:24:16 +01:00
Lucas WintherandClaude Opus 5.5 5f85ce1d4b feat(learner): library, search, course outline with gating, lesson payload API
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:23:30 +01:00
Lucas WintherandClaude Opus 5.5 a8a8e32bcb feat(learner): owner admin API for roles, groups, course access and library curation
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:20:49 +01:00
Lucas WintherandClaude Opus 5.5 668ae379bf feat(learner): Better Auth sessions, owner bootstrap, claim groups; server takes feature factories
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:20:06 +01:00
Lucas WintherandClaude Opus 5.5 9aa475329a feat(learner): Better Auth adapter over Bun.SQL for SQLite and Postgres
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:17:44 +01:00
Lucas WintherandClaude Opus 5.5 5a215744e5 feat(learner): package scaffold, auth tables migration, migrations runner
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:16:31 +01:00
Lucas WintherandClaude Opus 5.5 0b117159cd docs: WP-A learner package plan
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:15:48 +01:00
Lucas WintherandClaude Opus 5.5 3ca05fcfbc merge: Phase 0 contract
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:07:26 +01:00
Lucas WintherandClaude Opus 5.5 05eee4cd40 feat: server entry and web shell with design tokens
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:05:49 +01:00
Lucas WintherandClaude Opus 5.5 7f33169487 feat(core): config, job queue, range media serving, feature composition
Adds aclRepo to @stc/db for canView.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:04:46 +01:00
Lucas WintherandClaude Opus 5.5 ea18f18b4f fix(db): use DOUBLE PRECISION for position and progress columns
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:01:31 +01:00
Lucas WintherandClaude Opus 5.5 f061e36092 fix(db): jobs.update writes only patched columns; late progress cannot resurrect a finished job
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 03:01:05 +01:00
Lucas WintherandClaude Opus 5.5 4636273d55 feat(db): progress, notes, attempts, library, jobs repositories
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:59:09 +01:00
Lucas WintherandClaude Opus 5.5 738d813fb8 feat(db): Bun.SQL connection and portable migrations
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:57:34 +01:00
Lucas WintherandClaude Opus 5.5 f71a31a5f1 fix(course-format): validate anchor file via requireFile; real throw test for loadCourse catch
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:55:38 +01:00
Lucas WintherandClaude Opus 5.5 a82ab18bee fix(course-format): directories are not lesson files; a failing course never rejects loadAll
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:54:23 +01:00
Lucas WintherandClaude Opus 5.5 b8c65626f9 feat: overlay manifests for the two reference courses
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:52:24 +01:00
Lucas WintherandClaude Opus 5.5 c78c7ec8d8 feat(course-format): markdown extraction, discovery, loading, repository
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:51:26 +01:00
Lucas WintherandClaude Opus 5.5 7a68800f6f test: sample fixture course
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:50:00 +01:00
Lucas WintherandClaude Opus 5.5 7e7ce30535 feat(course-format): stcourse.yaml schema
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:49:42 +01:00
Lucas WintherandClaude Opus 5.5 3b15d87a5f feat(contracts): shared server, exercise, ai, import and web interfaces
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:48:10 +01:00
Lucas WintherandClaude Opus 5.5 9f582b99d2 chore: bun workspace scaffold
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:47:42 +01:00
Lucas WintherandClaude Opus 5.5 830a0cdd9b chore: ignore worktrees
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:46:38 +01:00
Lucas WintherandClaude Opus 5.5 29ba043de7 Add STCourses implementation plan
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:46:28 +01:00
lucasw89andClaude Opus 5.5 ab96addbab Add STCourses design, research report and approved mockup
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 02:37:38 +01:00