Commit Graph

152 Commits

Author SHA1 Message Date
giles
28a5cc37d0 Consume coop fragments for unified navigation
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m2s
Add middleware to fetch nav-tree, auth-menu, and cart-mini fragments
from coop apps. Update base.html to render coop nav with fallback.
Add internal URL env vars for Docker networking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:28:31 +00:00
giles
956da6df2e Skip silent auth check for /internal/ and /oembed paths
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m32s
Fragment and oEmbed endpoints must be accessible without authentication.
The silent auth middleware was returning 302 redirects, causing fragment
fetches from coop apps to silently fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:13:03 +00:00
giles
a3437f0069 Add nav-item + link-card fragments and oEmbed endpoint
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m1s
- nav-item fragment handler with template
- link-card fragment handler with CID-based lookup, friendly names, batch mode
- oEmbed router at GET /oembed for media/recipe/effect/run content
- Fragment templates in app/templates/fragments/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:44:13 +00:00
giles
fc93e27b30 Add fragment router for micro-frontend composition
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m10s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 08:28:01 +00:00
giles
7ec5609aac Clear session cookie when account signals logout via inbox
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m26s
Check did_auth:{device_id} in Redis — if absent while user has
a session cookie, account has logged out. Clear the cookie so
next request triggers prompt=none which won't re-auth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:26:17 +00:00
giles
80b423034d Fix actor_id: use email not display name
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m25s
actor_id must match DB records — always use username (email).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:13:52 +00:00
giles
eaefdd326b Fix healthcheck + external URL in silent auth middleware
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m27s
- Add /health endpoint, update healthcheck to use it
- Use configured base URL instead of internal Docker URL
- Add /health to skip prefixes for silent auth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:06:44 +00:00
giles
e1f13abc7f Fix middleware ordering: device_id must be outermost
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m4s
FastAPI runs the last-registered middleware first on request.
device_id_middleware was inner, so silent_auth_check's early
redirect bypassed it — cookie never set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:50:24 +00:00
giles
b294fd0695 Add AP inbox endpoint + device auth signaling
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m2s
- POST /inbox with HTTP Signature verification
- Device ID cookie tracking + adoption from account
- Silent auth checks local Redis for did_auth signals
- Replaces shared-Redis coupling with AP activity delivery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:41:33 +00:00
giles
ab3b6b672d Add silent auto-login via prompt=none OAuth check
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m24s
Middleware on every GET checks if user is logged in. If not, does a
silent prompt=none redirect to account. If account has an active
session, login completes invisibly. Otherwise sets a 5-minute cooldown
cookie to avoid redirect loops.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:43:08 +00:00
giles
49097eef53 Replace L2 JWT auth with OAuth SSO via account.rose-ash.com
- config.py: OAuth settings replace l2_server/l2_domain
- auth.py: full rewrite — login/callback/logout with itsdangerous
  signed state cookies and httpx token exchange
- dependencies.py: remove l2_server assignment, fix redirect path
- home.py: simplify /login to redirect to /auth/login
- base.html: cross-app nav (Blog, Market, Account) + Rose Ash branding
- requirements.txt: add itsdangerous

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:26:17 +00:00
gilesb
ca4e86d07e Fix S-expression syntax highlighting - HTML was leaking into displayed text
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m26s
Cascading regex replacements corrupted their own output: the string regex
matched CSS class names inside previously-generated span tags. Replaced with
a single-pass character tokenizer that never re-processes its own HTML output.
Also added highlighting to recipe detail page (previously had none).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:02:22 +00:00
gilesb
146db1c60f Remove hardcoded secrets from public repo
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m21s
- Replace hardcoded POSTGRES_PASSWORD, ADMIN_TOKEN, and L1 host IP
  with env var references in docker-compose.yml
- Remove default password fallback from database.py and app/config.py
- Update .env.example with required POSTGRES_PASSWORD, ADMIN_TOKEN, L1_HOST
- Update README to mark DATABASE_URL as required

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 18:46:55 +00:00
giles
48018d09b7 Add CI/CD workflow
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 1m2s
GPU Worker CI/CD / test (push) Failing after 1m4s
GPU Worker CI/CD / deploy (push) Has been skipped
2026-02-06 10:45:13 +00:00
giles
2f56ffc472 Fix live HLS streaming with dynamic quality playlist URLs
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions
The problem: HLS.js caches quality playlist URLs from the master playlist.
Even when we update the master playlist CID, HLS.js keeps polling the same
static quality CID URL, so it never sees new segments.

The fix:
- Store quality-level CIDs in database (quality_playlists JSONB column)
- Generate master playlist with dynamic URLs (/runs/{id}/quality/{name}/playlist.m3u8)
- Add quality endpoint that fetches LATEST CID from database
- HLS.js now polls our dynamic endpoints which return fresh content

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 21:07:29 +00:00
giles
4647dd52c8 Add IPFS proxy for live HLS streaming - rewrites playlist URLs 2026-02-04 21:00:07 +00:00
giles
e2761798a8 Unify HLS players with Live/Replay mode toggle
- Single player for both live rendering and completed HLS streams
- "From Start" mode plays from beginning (replay/VOD style)
- "Live Edge" mode follows rendering progress
- Uses dynamic playlist endpoint for both modes
- Removes duplicate VOD player code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:22:54 +00:00
giles
81dc40534c Add progress metadata to ipfs-stream endpoint
Returns progress, frame, total_frames from Celery task state
so clients can display rendering progress.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:16:17 +00:00
giles
d900df5aa0 Add View on IPFS button to effect and recipe detail pages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:56:12 +00:00
giles
13415fb420 Add Run Recipe and Delete buttons to recipe detail page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:43:32 +00:00
giles
d6c575760b Add Delete and Run Again buttons to run detail page
- Add "Run Again" button that reruns the recipe with same parameters
- Add "Delete" button with confirmation to delete run and artifacts
- Consolidate result display into single #action-result span
- Implement POST /runs/rerun/{recipe_id} endpoint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:18:16 +00:00
giles
9a8a701492 Fix GPU encoding black frames and improve debug logging
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions
- Add CUDA sync before encoding to ensure RGB->NV12 kernel completes
- Add debug logging for frame data validation (sum check)
- Handle GPUFrame objects in GPUHLSOutput.write()
- Fix cv2.resize for CuPy arrays (use cupyx.scipy.ndimage.zoom)
- Fix fused pipeline parameter ordering (geometric first, color second)
- Add raindrop-style ripple with random position/freq/decay/amp
- Generate final VOD playlist with #EXT-X-ENDLIST

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:33:12 +00:00
giles
baf79f453f Fix IPFS stream caching - return live playlist CID from database
- Return ipfs_playlist_cid from pending_runs while task is running
- Add Cache-Control: no-cache headers to prevent browser/CDN caching
- Fix streaming clients getting stale playlist CIDs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 12:32:56 +00:00
giles
ef4bc24eda Use GPUVideoSource for hardware-accelerated video decoding
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions
- CIDVideoSource now uses GPUVideoSource when GPU is available
- Enables CUDA hardware decoding for video sources
- Should significantly improve rendering performance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:03:16 +00:00
giles
0bd8ee71c7 Fix MP4 mux for web playback: add faststart and genpts
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions
- Add -movflags +faststart to move moov atom to start
- Add -fflags +genpts for proper timestamp generation
- Fixes jerky playback and video/audio desync

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:32:45 +00:00
giles
11bcafee55 Use IPFS URLs for video/image playback when available
Templates now prefer /ipfs/{cid} over /cache/{cid}/raw when
run.ipfs_cid is set. This fixes playback for content that exists
on IPFS but not on the local API server cache.

Also fixed field name: run.output_ipfs_cid -> run.ipfs_cid to match
database schema.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:15:09 +00:00
giles
9096824444 Redirect /hls/stream.m3u8 to IPFS playlist when available
When the local HLS playlist doesn't exist, check for IPFS playlist
CID in pending/completed run and redirect to the IPFS gateway.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:09:19 +00:00
giles
fe6730ce72 Add dev infrastructure improvements
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions
- Central config with logging on startup
- Hot reload support for GPU worker (docker-compose.gpu-dev.yml)
- Quick deploy script (scripts/gpu-dev-deploy.sh)
- GPU/CPU frame compatibility tests
- CI/CD pipeline for GPU worker (.gitea/workflows/gpu-worker.yml)
- Standardize GPU_PERSIST default to 0 across all modules

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 21:56:40 +00:00
giles
3116a70c3e Fix IPFS upload: sync instead of background task
The background IPFS upload task was running on workers that don't have
the file locally, causing uploads to fail silently. Now uploads go to
IPFS synchronously so the IPFS CID is available immediately.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 21:17:22 +00:00
giles
09d5359725 Re-enable GPU queue routing after image rebuild
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:38:37 +00:00
giles
4930eb99ad Temp: disable GPU queue for testing IPFS HLS streaming
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:25:50 +00:00
giles
86830019ad Add IPFS HLS streaming and GPU optimizations
- Add IPFSHLSOutput class that uploads segments to IPFS as they're created
- Update streaming task to use IPFS HLS output for distributed streaming
- Add /ipfs-stream endpoint to get IPFS playlist URL
- Update /stream endpoint to redirect to IPFS when available
- Add GPU persistence mode (STREAMING_GPU_PERSIST=1) to keep frames on GPU
- Add hardware video decoding (NVDEC) support for faster video processing
- Add GPU-accelerated primitive libraries: blending_gpu, color_ops_gpu, geometry_gpu
- Add streaming_gpu module with GPUFrame class for tracking CPU/GPU data location
- Add Dockerfile.gpu for building GPU-enabled worker image

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:23:16 +00:00
giles
5bc655f8c8 Include rendering status in runs list 2026-02-03 00:44:53 +00:00
giles
a57be27907 Add live video streaming for in-progress renders 2026-02-03 00:27:19 +00:00
giles
9302283e86 Add admin token support to runs list endpoint 2026-02-03 00:23:14 +00:00
giles
2d520cf256 Allow admin token auth for stream endpoint
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 23:37:57 +00:00
giles
2081092ce8 Add ADMIN_TOKEN for admin endpoints and allow token-based auth
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 23:28:19 +00:00
giles
d20eef76ad Fix completed runs not appearing in list + add purge-failed endpoint
- Update save_run_cache to also update actor_id, recipe, inputs on conflict
- Add logging for actor_id when saving runs to run_cache
- Add admin endpoint DELETE /runs/admin/purge-failed to delete all failed runs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 23:24:39 +00:00
giles
581da68b3b Add streaming endpoint to runs router
- Add /runs/stream POST endpoint for streaming recipes
- Accepts recipe_sexp, sources_sexp, audio_sexp
- Submits to run_stream Celery task

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 19:18:47 +00:00
giles
bb458aa924 Replace batch DAG system with streaming architecture
- Remove legacy_tasks.py, hybrid_state.py, render.py
- Remove old task modules (analyze, execute, execute_sexp, orchestrate)
- Add streaming interpreter from test repo
- Add sexp_effects with primitives and video effects
- Add streaming Celery task with CID-based asset resolution
- Support both CID and friendly name references for assets
- Add .dockerignore to prevent local clones from conflicting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 19:10:11 +00:00
gilesb
59c72500ac Fix status: check task result success flag, not just Celery success
Celery task "succeeds" (no exception) but may return {"success": False}.
Now we check the task result's success field AND output_cid before
marking run as completed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 02:13:03 +00:00
gilesb
84d465b264 Include failed runs in list_runs output
Failed runs were not showing in UI/CLI because list_runs only
included runs with status "pending" or "running", excluding "failed".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 02:10:58 +00:00
gilesb
d08fbfc0bd Fix SOURCE node resolution for user inputs in execute_recipe
- SOURCE nodes with :input true now resolve CID from input_hashes
- Tries multiple name formats: exact, lowercase-dashes, lowercase-underscores
- Only return "completed" status for runs with actual output
- Add integration tests for SOURCE CID resolution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 01:36:48 +00:00
gilesb
d603485d40 Refactor to S-expression based execution with code-addressed cache IDs
Major changes:
- Add execute_recipe task that uses S-expression planner
- Recipe S-expression unfolds into plan S-expression with code-addressed cache IDs
- Cache IDs computed from Merkle tree of plan structure (before execution)
- Add ipfs_client.add_string() for storing S-expression plans
- Update run_service.create_run() to use execute_recipe when recipe_sexp available
- Add _sexp_to_steps() to parse S-expression plans for UI visualization
- Plan endpoint now returns both sexp content and parsed steps

The code-addressed hashing means each plan step's cache_id is:
  sha3_256({node_type, config, sorted(input_cache_ids)})

This creates deterministic "buckets" for computation results computed
entirely from the plan structure, enabling automatic cache reuse.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 00:27:24 +00:00
gilesb
2c27eacb12 Convert DAG nodes dict to steps list in get_run_plan()
The CLI expects {"steps": [...]} but DAG format stores {"nodes": {...}}.
Added _dag_to_steps() to convert between formats, including topological
sorting so sources appear first.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 00:00:00 +00:00
gilesb
3e3df6ff2a Code-addressed node IDs and remove JSON index files
- Compiler now generates SHA3-256 hashes for node IDs
- Each hash includes type, config, and input hashes (Merkle tree)
- Same plan = same hashes = automatic cache reuse

Cache changes:
- Remove index.json - filesystem IS the index
- Files at {cache_dir}/{hash}/output.* are source of truth
- Per-node metadata.json for optional stats (not an index)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 22:38:50 +00:00
gilesb
da4e2e9d3d Fix stats counting to use ownership-based database queries
- Media: Only count video/image/audio/unknown types, not effects/recipes
- Effects: Use database count_user_items instead of filesystem scan
- Recipes: Use database count_user_items instead of loading all recipes

This ensures stats reflect user ownership via item_types table,
and prevents effects from being double-counted as media.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:51:14 +00:00
gilesb
6c973203fc Add debug logging to recipe upload and get
To help diagnose why recipes are not found after upload.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:35:06 +00:00
gilesb
7e38b4a0c8 Fix undefined cache_manager in clear_user_data
Call get_cache_manager() to get the cache manager instance
before using it in effects and media deletion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:10:22 +00:00
gilesb
8bf6f87c2a Implement ownership model for all cached content deletion
- cache_service.delete_content: Remove user's ownership link first,
  only delete actual file if no other owners remain

- cache_manager.discard_activity_outputs_only: Check if outputs and
  intermediates are used by other activities before deleting

- run_service.discard_run: Now cleans up run outputs/intermediates
  (only if not shared by other runs)

- home.py clear_user_data: Use ownership model for effects and media
  deletion instead of directly deleting files

The ownership model ensures:
1. Multiple users can "own" the same cached content
2. Deleting removes the user's ownership link (item_types entry)
3. Actual files only deleted when no owners remain (garbage collection)
4. Shared intermediates between runs are preserved

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:02:27 +00:00