Commit Graph

2455 Commits

Author SHA1 Message Date
Thomas Hallock 8a1c1c0c8f chore: trigger storybook v4
Deploy Storybook / Build and Deploy Storybook (push) Has been cancelled Details
2026-01-25 05:51:17 -06:00
Thomas Hallock 74565b93af fix(tracing): use resourceFromAttributes for OTel SDK 2.x compatibility
@opentelemetry/resources v2.x changed the API - Resource class constructor
was replaced with resourceFromAttributes() factory function.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 16:57:05 -06:00
Thomas Hallock dcad5bca46 feat(observability): add OpenTelemetry tracing with Tempo backend
- Add instrumentation.js for OTel SDK bootstrap via --require flag
- Add tracing.ts utility functions (getCurrentTraceId, recordError, withSpan)
- Install @opentelemetry packages for auto-instrumentation
- Update Dockerfile to copy instrumentation.js and use --require
- Add trace IDs to error responses in API routes

Traces are exported to Tempo via OTLP/gRPC when running in production
(KUBERNETES_SERVICE_HOST env var present).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 16:31:18 -06:00
Thomas Hallock 74e12c0029 feat(metrics): add session tracking and Grafana dashboard provisioning
- Add heartbeat-based session tracking (/api/heartbeat)
- Track active sessions, session duration, page views, unique visitors
- Use Page Visibility API to only send heartbeats when tab visible
- Add Grafana dashboard via ConfigMap provisioning
- Dashboard includes: sessions, Socket.IO, request rate, error rate,
  arcade games, worksheets, memory, event loop lag

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:40:55 -06:00
Thomas Hallock ef75a07c2c feat(metrics): add comprehensive application metrics
Expand Prometheus metrics to track:
- HTTP request timing and counts
- Socket.IO connections and events
- Database query timing
- Practice sessions and problems
- Arcade games (completions, scores, win rates)
- Worksheet generations (by operator, timing)
- Flashcard generations
- Flowchart views
- Vision/camera recordings
- Classroom and user activity
- Curriculum/BKT metrics
- LLM API calls
- Error tracking

Instrument key API endpoints:
- /api/game-results: Track game completions and scores
- /api/create/worksheets: Track worksheet generations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 14:05:30 -06:00
Thomas Hallock 35856afb2e feat(observability): add Prometheus/Grafana monitoring stack
- Deploy kube-prometheus-stack to k3s cluster via Terraform
- Add Prometheus metrics endpoint (/api/metrics) using prom-client
- Track Socket.IO connections, HTTP requests, and Node.js runtime
- Configure ServiceMonitor for auto-discovery by Prometheus
- Expose Grafana at grafana.dev.abaci.one
- Expose Prometheus at prometheus.dev.abaci.one

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 12:45:32 -06:00
Thomas Hallock 5258437bef feat(dev): add dev.abaci.one for build artifacts
- Add nginx static server at dev.abaci.one for serving:
  - Playwright HTML reports at /smoke-reports/
  - Storybook (future) at /storybook/
  - Coverage reports (future) at /coverage/

- NFS-backed PVC shared between artifact producers and nginx
- Smoke tests now save HTML reports with automatic cleanup (keeps 20)
- Reports accessible at dev.abaci.one/smoke-reports/latest/

Infrastructure:
- infra/terraform/dev-artifacts.tf: nginx deployment, PVC, ingress
- Updated smoke-tests.tf to mount shared PVC
- Updated smoke-test-runner.ts to generate and save HTML reports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:52:26 -06:00
Thomas Hallock 87bce550ad fix(smoke-tests): report last completed run instead of running test
Changed status endpoint to report the last COMPLETED test run instead
of any running test. This prevents Gatus from showing unhealthy status
while tests are in progress. Added currentlyRunning flag for info.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:39:45 -06:00
Thomas Hallock d2be19f1be fix(smoke-tests): simplify tests to only reliable critical paths
Removed tests for pages that were timing out or failing due to
hydration issues. Smoke tests should be minimal and reliable -
they detect if the site is down, not comprehensively test features.

Kept: homepage (3 tests), flowchart (1 test), arcade game (1 test),
practice navigation (1 test) = 6 total tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 09:08:47 -06:00
Thomas Hallock 5ba12ef4cc fix(smoke-tests): update Playwright Docker image to v1.56.0
The smoke tests were failing because the Playwright package (1.56.0)
didn't match the Docker image version (v1.55.0-jammy). Updated the
Dockerfile to use mcr.microsoft.com/playwright:v1.56.0-jammy.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 07:42:06 -06:00
Thomas Hallock aa6506957c revert: undo performance changes that broke intervention badges
Reverts the following commits that traded functionality for
marginal (or negative) performance gains:

- Skip intervention computation during SSR (broke badges)
- Defer MiniAbacus rendering (caused visual flash)
- Batch DB queries with altered return type
- Eliminate redundant getViewerId calls

The intervention badges are critical for parents/teachers to
identify students who need help. Performance should not
compromise core functionality.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 06:51:17 -06:00
Thomas Hallock 1914bcf9d0 perf(practice): eliminate redundant getViewerId and user lookups
Refactor getPlayersWithSkillData() to return viewerId and userId
along with players, avoiding 2 redundant calls in Practice page:
- Previous: 3 calls to getViewer() (via getViewerId) + 2 user lookups
- Now: 1 call to getViewer() + 1 user lookup

This should reduce Practice page SSR time by eliminating duplicate
auth checks and database queries.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 05:46:03 -06:00
Thomas Hallock dbc45b97b0 fix(smoke-tests): correct Playwright test path argument
The testDir in playwright.config.ts is './e2e', so we should pass 'smoke'
not 'e2e/smoke' to avoid looking in ./e2e/e2e/smoke.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 05:44:13 -06:00
Thomas Hallock affad2f4a6 feat(monitoring): add E2E smoke tests with Gatus integration
Add Playwright-based smoke tests that run every 15 minutes via k8s CronJob,
with results exposed to Gatus for status.abaci.one monitoring.

- Add smoke_test_runs table for storing test results
- Add /api/smoke-test-status endpoint (Gatus checks this)
- Add /api/smoke-test-results endpoint (CronJob reports here)
- Add smoke tests for homepage, arcade, practice, and flowchart pages
- Add smoke-test-runner.ts script
- Add Dockerfile.smoke-tests based on Playwright image
- Add GitHub Actions workflow to build smoke tests image
- Add Kubernetes CronJob Terraform config
- Update Gatus config with Browser Smoke Tests endpoint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 05:08:50 -06:00
Thomas Hallock 958481b661 perf(homepage): defer MiniAbacus rendering until after hydration
- Skip heavy AbacusReact SVG rendering during SSR
- Render placeholder during SSR and initial hydration
- AbacusReact loads after client hydration
- Reduces SSR overhead by avoiding 4x AbacusReact renders

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 05:05:59 -06:00
Thomas Hallock 1e2f5c9010 perf(practice): skip intervention computation during SSR
Intervention badges are helpful but not critical for initial render.
By skipping the expensive BKT computation (which requires N additional
database queries for session history), we significantly reduce SSR time.

- Batched skill mastery query: N queries → 1 query
- Skipped intervention computation: N additional queries → 0

The intervention data can be computed lazily on the client if needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:14:37 -06:00
Thomas Hallock ed653db483 perf(practice): batch DB queries to reduce N+1 pattern
- Single query for all skill mastery records instead of N queries
- Single query for session history instead of N queries per player
- Group results in memory for O(1) lookups
- Expected improvement: ~150ms reduction in SSR time

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:42:49 -06:00
Thomas Hallock 30fb0e86e3 perf(worksheets): defer preview to client-side API fetch
The RSC Suspense streaming approach didn't work because the Suspense
boundary was inside a client component's props - React serializes all
props before streaming can begin.

Simpler solution: Don't embed the 1.25MB SVG in initial HTML at all.
- Page SSR returns immediately with just settings (~200ms TTFB)
- Preview is fetched via existing API after hydration (server-side generation)
- User sees page shell instantly, preview loads with loading indicator

This achieves the same UX goal: fast initial paint, preview appears when ready.
The preview generation still happens server-side via the API endpoint.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 19:29:59 -06:00
Thomas Hallock ba08409269 docs: add Keel and k8s deployment notes to agent instructions
Document lessons learned:
- Keel annotations must be on workload metadata, not pod template
- Keel namespace watching configuration
- Debugging Keel polling issues
- LiteFS replica migration handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 19:23:28 -06:00
Thomas Hallock 2b5d66f776 perf(worksheets): use Suspense streaming for preview generation
Problem: The worksheet page had 1.7-2.3s TTFB because the 1.25MB SVG
preview was being serialized into the initial HTML response, blocking
first paint.

Solution: Use React Suspense to stream the preview separately:
- Page shell renders immediately with settings (~200ms TTFB)
- Preview generates async and streams in when ready (~1.5s later)
- User sees the UI instantly, preview appears with loading skeleton

New components:
- StreamedPreview: async server component that generates preview
- PreviewSkeleton: loading placeholder while streaming
- StreamedPreviewContext: shares streamed data with PreviewCenter
- PreviewDataInjector: bridges server-streamed data to client context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:54:17 -06:00
Thomas Hallock e72018ae44 fix(server): skip migrations on LiteFS replicas
LiteFS replicas are read-only, so migrations fail with "read only replica"
error. Check LITEFS_CANDIDATE env var and skip migrations on replicas.
The primary (pod-0) will run migrations and replicate the changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:31:19 -06:00
Thomas Hallock 1f1083773d perf: add timing instrumentation to worksheet page SSR
Track where time is spent during worksheet page render:
- loadWorksheetSettings (DB query + getViewerId)
- generateWorksheetPreview (problem generation + Typst compilation)
- Total page render time

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:21:12 -06:00
Thomas Hallock 3d835d67cd feat(flowchart-workshop): add version history with preview mode
- Add flowchart_version_history table to store snapshots after generate/refine
- Create versions API endpoint (GET list, POST restore)
- Add History tab with version list showing source, validation status, timestamp
- Implement inline preview mode to view historical versions without restoring
- Preview mode shows amber banner and updates diagram, examples, worksheet, tests
- Hide structure/input tabs (not useful currently)
- Add preview notice in refinement panel clarifying behavior
- Update React Query documentation with comprehensive patterns
- Add versionHistoryKeys to central query key factory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 13:52:59 -06:00
Thomas Hallock 325e0f483e fix(flowchart-workshop): fix LLM streaming for generation and reconnection
- Fix race condition where watch endpoint couldn't find active generation
  because generate hadn't registered yet. Workshop page now triggers
  /generate before connecting to /watch.

- Add polling fallback in watch endpoint (up to 3s) for edge cases where
  generate route is still starting up.

- Add progress panel for regeneration - was missing because the panel
  was only shown when !hasDraft.

- Add comprehensive logging throughout generation pipeline for debugging.

- Improve generation registry with subscriber management and accumulated
  reasoning text for reconnection support.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 13:02:34 -06:00
Thomas Hallock c845281a60 perf(homepage): optimize SSR with deferred processing and dynamic imports
- Defer tutorial processing to after hydration (~100-200ms savings)
- Dynamic import TutorialPlayer, InteractiveFlashcards, LevelSliderDisplay with ssr:false
- Add skeleton placeholders to prevent layout shift
- Parallelize headers/cookies access in i18n/request.ts
- Add missing flowchart definitions (order-of-operations, sentence-type)

Target: Reduce homepage SSR from 300-500ms to ~100-150ms

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 11:40:54 -06:00
Thomas Hallock fc15334aec fix(flowcharts): improve edge highlighting with BFS traversal for phase boundaries
- Rewrite DebugMermaidDiagram edge matching to use BFS graph traversal
- Build graph from SVG edges (L_FROM_TO_INDEX format) for path finding
- Handle phase boundary disconnections with bidirectional BFS:
  - Forward BFS finds all nodes reachable from start
  - Backward BFS finds all nodes that can reach end
  - Combines both to highlight intermediate nodes across phase gaps
- Remove complex pattern matching in favor of graph-based approach
- Auto-compute edge IDs as {nodeId}_{optionValue} in loader.ts
- Add computeEdgeId() helper to schema.ts for consistent edge ID generation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 10:28:02 -06:00
Thomas Hallock f2fc30878d fix(flowcharts): auto-infill missing edge IDs instead of warning
Instead of warning about missing edge IDs in the doctor, automatically
assign computed edge IDs ({nodeId}_{optionValue}) to decision edges
that have auto-generated IDs (edge_N) during flowchart loading.

This makes edge highlighting work for legacy flowcharts without
requiring regeneration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 09:04:02 -06:00
Thomas Hallock 37be1c8c65 feat(flowcharts): add reliable edge ID matching for visualization
- Add computeEdgeId() helper that generates edge IDs as {nodeId}_{optionValue}
- Update loader.ts to compute edge IDs automatically from decision options
- Update parser.ts to extract edge IDs from mermaid id@--> syntax
- Add MERM-003 diagnostic in doctor.ts to detect missing edge IDs
- Update LLM schemas to document the required edge ID pattern
- Update DebugMermaidDiagram to match edges by ID (with index fallback)

Edge IDs enable reliable highlighting of decision edges during visualization.
The pattern is deterministic: for a decision node "COMPARE" with option
value "direct", the expected edge ID is "COMPARE_direct".

Mermaid content must use: COMPARE COMPARE_direct@-->|"DIRECT"| NEXT_NODE

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 08:59:05 -06:00
Thomas Hallock 2e72eea7d0 feat(flowcharts): add Problem Trace and unify answer computation (Phases 3-5)
Phase 3 - Mermaid Highlighting:
- Add highlightedNodeId prop to DebugMermaidDiagram for trace hover highlighting
- Cyan dashed border distinguishes trace hover from walker progress (amber)

Phase 4 - Problem Trace Component:
- Create ProblemTrace.tsx displaying step-by-step computation trace
- Shows node title, transforms applied, working problem evolution
- Timeline UI with expand/collapse for each step
- Integrate into WorksheetDebugPanel expanded details

Phase 5 - Unified Answer Computation:
- Update WorksheetDebugPanel to use simulateWalk + extractAnswer
- Update worksheet-generator.ts to use unified computation path
- Update test-case-validator.ts runTestCaseWithFlowchart to use simulateWalk
- All places with full ExecutableFlowchart now use single code path

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 17:07:21 -06:00
Thomas Hallock ae276455fa feat(flowcharts): implement unified computation model (Phases 1-2)
Transform the flowchart system from "compute everything upfront" to
"walk IS the computation". This is the foundation for the new unified
computation model.

Phase 1 - Schema & Core Runtime:
- Add TransformExpression, StateSnapshot, DisplayTemplate, AnswerDefinition
- Add StructuredTestCase for primitive-based test validation
- Update FlowchartState with values, snapshots, hasError fields
- Mark variables as deprecated (optional) for transition period
- Add interpolateTemplate() for {{name}} and {{=expr}} syntax
- Add applyTransforms(), extractAnswer(), simulateWalk() to loader
- Add createContextFromValues() for transform execution

Phase 2 - Walker Integration:
- Apply transforms when entering each node during walk
- Initialize entry node transforms on state creation
- Snapshots now accumulate as nodes are visited

All existing flowcharts continue to work via backwards compatibility
with the legacy variables section.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:39:20 -06:00
Thomas Hallock cdd53f6602 feat(llm-client): add configurable logging system
Add a flexible logging system to the llm-client package that can be
enabled/disabled without rebuilding:

- Add Logger class with configurable enable/disable and custom logger support
- Add LogLevel, LoggerFn, LoggingConfig types
- Add `debug` option to LLMStreamRequest for per-request logging override
- Add setLogging() method for runtime enable/disable
- Replace hardcoded console.log in openai-responses provider with logger
- Add ?debug=true query param to flowchart generate endpoint

Usage:
- Per-request: llm.stream({ ..., debug: true })
- Global: llm.setLogging({ enabled: true })
- Custom logger: new LLMClient({ logging: { enabled: true, logger: fn } })

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:17:31 -06:00
Thomas Hallock 454f93faae feat(flowcharts): migrate hardcoded flowcharts to database seeds
Hardcoded flowcharts are now "seeds" that can be manually populated
into the database via a debug UI. This provides a single source of
truth (database) while keeping canonical definitions in version control.

Changes:
- Add /api/flowcharts/seeds endpoint for seed management
- Add SeedManagerPanel component (visible in debug mode on /flowchart)
- Rename FLOWCHARTS -> FLOWCHART_SEEDS in definitions/index.ts
- Remove hardcoded fallbacks from getFlowchartByIdAsync/getFlowchartListAsync
- Update browse API to only load from database
- Update all dependent files to use database-only loading
- Seeds are owned by the user who initiates seeding

To use: Enable debug mode on /flowchart, use Seed Manager panel to
populate the database with built-in flowcharts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:34:14 -06:00
Thomas Hallock 27310e0b68 fix(middleware): pass guest ID via request headers instead of response headers
Server components read from request headers, not response headers.
This fixes the "No valid viewer session found" error for new visitors
on pages like /practice that need guest identification on first load.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 11:47:18 -06:00
Thomas Hallock 6c51182c15 refactor(flowchart): remove legacy schema-specific formatting, add display.problem check
- Remove legacy schema-specific formatting fallbacks in formatting.ts and example-generator.ts
- All flowcharts now require explicit display.problem and display.answer expressions
- Add DISP-003 diagnostic for missing display.problem expressions
- Update doctor to treat missing display.answer as error (was warning)

Also includes:
- Terraform: generate LiteFS config at runtime, add AUTH_TRUST_HOST, add volume mounts for vision-training and uploads data
- Terraform: add storage.tf for persistent volume claims
- Add Claude instructions for terraform directory
- Various UI component formatting updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 11:03:15 -06:00
Thomas Hallock c2218af47e feat(flowchart): add test case validation system with coverage analysis
- Add expectedAnswer field to ProblemExample schema for test validation
- Create test-case-validator.ts with functions to evaluate display.answer
  and compare against expected answers
- Add TestsTab.tsx component showing test results and path coverage
- Integrate validation into generate/refine routes with SSE events
- Add coverage diagnostics to flowchart doctor (TEST-001/002/003)
- Fix LLM output normalization: strip wrapper quotes from strings
  (e.g., "'+'" -> "+") and convert numeric strings to numbers
- Use formatAnswerDisplay for test evaluation (same as worksheet)
- Update LLM prompts with clearer excludeFromExampleStructure guidance
  for result-formatting decisions vs problem-type decisions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:23:07 -06:00
Thomas Hallock 2765b081bc fix(litefs): simplify candidate env var and add debug logging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:50:02 -06:00
Thomas Hallock 8b39673c8d fix(litefs): correct migrate.js path to dist/db/migrate.js
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:10:57 -06:00
Thomas Hallock bb9a4be6c2 fix(litefs): remove invalid primary-redirect-url config field
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:44:49 -06:00
Thomas Hallock e69a33838a feat(infra): add LiteFS for distributed SQLite in k8s
- Add LiteFS binary and config to Docker image for SQLite replication
- Convert k8s Deployment to StatefulSet for stable pod identities
- Pod-0 is primary (handles writes), others are replicas
- LiteFS proxy forwards write requests to primary automatically
- Add headless service for pod-to-pod communication
- Increase Node.js heap size to 4GB for Next.js build
- Exclude large Python venvs from Docker context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:19:37 -06:00
Thomas Hallock 24ce7475f0 fix(web): convert Panda CSS shorthand padding/margin to separate props
Panda CSS token values in shorthand strings (e.g., `padding: '2 4'`)
silently fail. Convert all 84+ occurrences to paddingX/paddingY and
marginX/marginY properties which correctly resolve design tokens.

Affected areas:
- Flowchart pages and components
- Know Your World game components
- KidNumberInput component

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:38:40 -06:00
Thomas Hallock c29388df30 refactor(docs): consolidate .claude instructions (53% reduction)
- Delete 10 obsolete files (roadmaps, specs, historical artifacts)
- Merge 5 arcade docs into ARCADE_SYSTEM.md (2,274 → 309 lines)
- Condense merge conflicts (707 → 126 lines)
- Rewrite CLAUDE.md (262 → 94 lines)
- Update README.md with new structure

Before: 42 files, ~13,600 lines
After: 25 files, 6,389 lines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:15:26 -06:00
Thomas Hallock 87e76a514b chore: update local settings with new allowed commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:16:11 -06:00
Thomas Hallock 367edc8f82 refactor: rename .claude/skills to .claude/procedures
Avoid terminology confusion - "skills" refers to invokable commands
like /fix-css and /porkbun-dns. The documentation files are
step-by-step procedures, not invocable skills.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:14:42 -06:00
Thomas Hallock a36303be1c refactor: agent instructions Phase 4 - add index and restore merge conflicts
- Add .claude/README.md index categorizing all 34 docs
- Restore Merge Conflict section reference to CLAUDE.md
- Categorize docs: Skills, Reference, Architecture, Specs, Settings, Ops, Research, Roadmaps

Final CLAUDE.md: 262 lines (83% reduction from 1,531)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:09:57 -06:00
Thomas Hallock 69098e3038 refactor: agent instructions Phase 2+3 - CLAUDE.md now 258 lines
Phase 2:
- Extract React Query patterns to reference/react-query-mutations.md
- Extract TensorFlow debugging to reference/tensorflow-browser-debugging.md
- Extract Abacus Visualizations to reference/abacus-react.md
- Slim Production Dependencies (73→7 lines)
- Slim Code Factoring (75→9 lines)
- Slim Data Attributes (49→9 lines)

Phase 3:
- Consolidate 3 CRITICAL behavioral sections (92→12 lines)
- Slim Merge Conflict, Z-Index, Animation, Game Settings sections
- Slim Flowchart Walker, Daily Practice, Rithmomachia
- Remove duplicate package.json scripts section
- Consolidate workflow and dev server sections

Total reduction: 1,531 → 258 lines (83% smaller)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:07:09 -06:00
Thomas Hallock a3409fff38 refactor: agent instructions Phase 1 + dark mode modal fixes
Dark mode improvements:
- Fix DeploymentInfoModal background, title, footer colors
- Fix badge contrast (StatusBadge, CodeBadge) with raw rgba/hex values
- Fix padding syntax (Panda CSS gotcha: '1 2' → '4px 8px')

Agent instructions refactoring:
- Slim CLAUDE.md from 1,531 to 1,148 lines (-25%)
- Create .claude/skills/database-migrations.md (consolidated skill)
- Create .claude/reference/panda-css.md (styling gotchas)
- Delete 40+ stale plan/status docs (16k+ lines removed)
- Consolidate duplicate migration sections
- Add skills/ and reference/ directory structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 09:49:10 -06:00
Thomas Hallock e9c4bb1ed8 fix(flowchart): implement proper task queue for concurrent example generation
Replace sequential example generation with a proper task queue system that
correctly handles concurrent requests to the Web Worker pool.

Root cause of previous issues: Each worker stored only ONE resolve/reject
callback, so concurrent requests would overwrite each other's callbacks,
causing promises to never resolve or resolve with wrong data.

Solution:
- Add unique requestId to all worker messages for request/response matching
- Implement task queue with dispatch logic for pending work
- Track pending requests in a Map keyed by requestId
- Workers echo back requestId so responses match their originating requests
- Both /flowchart page and workshop page now generate concurrently

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:51:36 -06:00
Thomas Hallock de720ab39b fix(flowchart): sequence example generation to avoid web worker conflicts
When both WorksheetDebugPanel and FlowchartExampleGrid try to generate
examples simultaneously using the shared web worker pool, the workers'
resolve/reject callbacks get overwritten, causing one request to never
complete.

This fix sequences the generation:
- WorksheetDebugPanel generates first (when worksheet tab is active)
- FlowchartExampleGrid waits until WorksheetDebugPanel signals completion
- Added onGenerationStart/onGenerationComplete callbacks to WorksheetDebugPanel
- Added waitForReady prop to FlowchartExampleGrid to defer generation
- Workshop page coordinates the sequence using isDebugPanelGenerating state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:14:07 -06:00
Thomas Hallock 83c2f261c0 fix(flowchart): add node ID mismatch detection and graceful error handling
- Add MERM-002 doctor diagnostic to detect when JSON node IDs don't
  match mermaid node IDs
- Update loader to throw error when entry node is missing or >50% of
  nodes are missing from mermaid (prevents crash loops)
- Add flowchartLoadError state and UI display in workshop page
- Improve LLM schema documentation for display.answer vs generation.target
- Add context-aware division-by-zero suggestions in doctor

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 19:05:36 -06:00
Thomas Hallock 86fe99e5c2 fix(flowchart): unify example generation for published and draft cards
- Combine published and draft example generation into single unified effect
- Fix race condition where worker pool was cancelling requests when
  drafts and published flowcharts competed for the same workers
- Add draftMermaidContent to sessions API response (was missing)
- Remove redundant draftCardExamples state in favor of unified cardExamples
- Process all flowcharts sequentially to avoid worker pool cancellation
- Show animated backgrounds on healthy draft flowcharts, not just published

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 18:01:37 -06:00