# Nebula Nodes — Session Handoff (2026-04-18)

> **How to use this doc:** paste the full contents into the first message of the next session. The new agent should be productive immediately after reading it + today's activity log at `~/.claude/activity/2026-04-18.log`.

This handoff layers on top of `.planning/handoff-2026-04-17.md` — read that first for the deeper project history, then come back here for what changed in the 2026-04-17/18 sessions.

---

## TL;DR

- OSS v1 "three pillars" are the only things that matter right now: **BYOK, nodes working, Claude chat fluency**. Everything else is deferred.
- Completed a full FAL gap-report triage (all tiers), built a Runway provider skill, added Seedance 2.0 Fast tier nodes, and live-tested both fast endpoints end-to-end.
- **Mac app is explicitly deferred** until OSS web is "in a good spot." Don't suggest Mac-side work.
- Current branch: `feat/3d-mesh-support`. Four new commits today sitting on top of in-flight chat panel + 3D mesh WIP (still uncommitted).

---

## Critical working rules (read every session)

1. **Verify-Before-Reporting** (`~/.claude/CLAUDE.md`). For any factual claim about a library/API/product, fetch the canonical primary source before stating it. WebSearch → discover URLs. WebFetch/curl → extract facts. Never synthesize from snippets.
2. **Research Protocol** (`~/.claude/rules/research-protocol.md`). Before any research: `_hot.md` → `_index.md` → topic note. Write back to all four files when done.
3. **Activity Logging** (`~/.claude/rules/activity-logging.md`). Log each meaningful task via `bash ~/.claude/scripts/activity-log.sh write "..."`. The log at `~/.claude/activity/2026-04-18.log` is the single source of truth for what happened today.
4. **Dual-param architecture** (memory `feedback_dual_params.md`). Nodes with FAL + direct routes must use `sharedParams` / `falParams` / `directParams`. Never merge.
5. **v1 essentials frame** (memory `project_v1_essentials.md`). Before adding any feature, ask: does it strengthen BYOK, node correctness, or Claude fluency? If no, park it.
6. **Mac app gating** (memory `project_mac_app_gating.md`). Do not start Mac-native work until the OSS web version is solid + 10–20 dogfood sessions pass.

---

## What got done in the 2026-04-17 → 2026-04-18 sessions

### 1. FAL gap report — all tiers applied (commit `a5ce56e`)

**Tier 1 bugs fixed:**
- `wan-2-6-i2v` / `wan-2-6-r2v`: dropped spurious `fal-ai/` prefix (endpoints are `wan/v2.6/...`)
- `veo-3`: split `aspectRatio` (Google direct, camelCase) from `aspect_ratio` (FAL, snake_case) across `directParams` / `falParams`. Original report recommendation to just drop `aspectRatio` would have broken the Google direct route.

**Tier 2 feature gaps:**
- Meshy FAL nodes: `enable_rigging`, `rigging_height_meters`, `enable_animation`, `animation_action_id` + `texture_image` port with URL rename
- Sora-2: `model` picker that routes to `/pro` endpoint when selected
- Flux Schnell: replaced phantom `aspect_ratio` with FAL's actual `image_size`; added `guidance_scale`, `num_inference_steps`, `output_format`, `acceleration`
- Kling-v3: `multi_prompt` (JSON textarea, parsed in handler) + `shot_type`

**Tier 3 polish:**
- fast-sdxl: steps, expand_prompt, loras + embeddings (JSON parsed), format, safety_checker
- `num_images` on flux-kontext, flux-2-pro, gpt-image-1-5 (+ edit)
- seedream-4-5: `max_images` + `enable_safety_checker`
- `enable_safety_checker` on flux-2-pro, recraft-v4-raster
- veo-3: `auto_fix`, `generate_audio`

**Tier 4 skill backfill (9 new files in `.claude/skills/fal/skills/`):**
wan v2.6 reference-to-video · kling-video v2.1/pro/image-to-video · kling-video o3/standard/image-to-video · luma ray-2 + image-to-video · ltx-2/image-to-video · pixverse/v4.5/text-to-video · bytedance seedance v1.5/pro/image-to-video · hunyuan3d-v3/text-to-3d.

**Bonus bug found during Tier 4:** `seedance-v1-5` endpoint `fal-ai/seedance/v1.5/text-to-video` doesn't exist on FAL. Corrected to `fal-ai/bytedance/seedance/v1.5/pro/image-to-video` (image-to-video only) and added required `image` + optional `end_image` input ports.

**Handler changes:**
- `backend/handlers/fal_universal.py`: port→URL renames for `texture_image`, `end_image`, `tail_image`
- `backend/execution/sync_runner.py`: JSON parsing for `kling-v3.multi_prompt` and `fast-sdxl.loras`/`embeddings` before FAL submit

### 2. Provider skills tracked (same commit)

`.claude/` moved from untracked to tracked. Four skills committed:
- `fal/` — 160-skill FAL bundle copied from user's Obsidian vault, plus the 9 backfills
- `meshy/` — docs.meshy.ai-sourced
- `gemini/` — Gemini + Imagen + Nano Banana + Veo prompting
- `runway/` — Stainless-SDK-sourced reference (built today from scratch against `github.com/runwayml/sdk-python`)

### 3. FAL SKILL.md staleness caught and fixed (commit `1f44110`)

During skill testing, Test 2 ("what endpoint does seedance-v1-5 now map to?") revealed the top-level FAL `SKILL.md` routing table hadn't caught up to the endpoint fixes made earlier in the same session. Fixed:
- Wan 2.6 i2v/r2v: dropped the `fal-ai/` prefix
- seedance-v1-5: corrected endpoint + skill-file link
- sora-2: now shows `/text-to-video` OR `.../pro` (dynamic)
- hunyuan3d-text-to-3d, ltx-video-2, luma-ray2-t2v, pixverse-v4-5, wan-2-6-r2v: linked to the newly-backfilled skill files

**Open drift risk:** the FAL top-level routing table and `backend/execution/sync_runner.py` can diverge. Worth a lint/check script before v1 ships.

### 4. Seedance 2.0 Fast tier (commit `7f59943`)

FAL has two "fast" variants of Seedance 2.0 we weren't wrapping:
- `bytedance/seedance-2.0/fast/text-to-video`
- `bytedance/seedance-2.0/fast/image-to-video`

Added two nebula nodes (`seedance-2-fast-t2v`, `seedance-2-fast-i2v`), registered handlers, updated the FAL SKILL.md routing table. Same params as the standard tier, cheaper ($0.2419/s at 720p), quicker. **Seedance 2.0 is the newest Seedance release** as of 2026-04-17 (released 2026-04-01) — there's no 2.1 or 3.0.

### 5. Live end-to-end test (stored at `/tmp/nebula-test/`)

Both fast-tier endpoints fired against FAL with real credits, mirroring nebula's `fal_universal.py` flow:

| Test | Endpoint | Submit | Queue time | Output |
|---|---|---|---|---|
| T2V | `bytedance/seedance-2.0/fast/text-to-video` | 200 | 110s | 784 KB MP4 |
| I2V | `bytedance/seedance-2.0/fast/image-to-video` | 200 | 80s | 1.21 MB MP4 |

Validated:
- `FAL_KEY` loads from `settings.json` correctly
- `POST /queue.fal.run/{endpoint}` → `request_id` + `status_url` + `response_url` ✅
- `IN_QUEUE` → `IN_PROGRESS` → `COMPLETED` transitions match `fal_universal.py` expectations ✅
- Output shape `{"video": {"url": "..."}}` matches `_parse_fal_output()` ✅

**I2V quirk discovered:** Not every public JPG works as `image_url`. The LTX-2 example JPG triggered HTTP 422 at the response-URL fetch even though status showed `COMPLETED` in ~6s (vs. 60-120s for real generations). A FAL-hosted WebP worked fine. Documented in the skill file (commit `353ee43`). If you see status=COMPLETED in <10s with a 422 on response fetch, the source image is the culprit.

---

## Current state

### Branch

`feat/3d-mesh-support` is ahead of `main` by many commits. The last four are from this session:

```
353ee43 docs(fal): note source-image quirk in seedance-2.0 fast i2v skill
7f59943 feat: add Seedance 2.0 Fast tier nodes (t2v + i2v)
1f44110 fix(skills): sync FAL routing table with today's endpoint changes
a5ce56e feat: FAL gap fixes + provider skills (FAL, Meshy, Gemini, Runway)
2ae56dc docs: add chat panel handoff spec for next session     ← pre-today
549ef02 docs: add CLI spec, implementation plan, model reference, and research
```

### Uncommitted (intentionally left from prior sessions)

These are in-flight WIP for **chat panel** and **3D mesh support** work. Do NOT bundle them into unrelated commits — the prior agent left them out on purpose.

```
M  backend/cli/commands/quick.py
M  backend/handlers/meshy.py
M  backend/main.py
M  frontend/src/App.tsx
M  frontend/src/components/Canvas.tsx
M  frontend/src/components/nodes/ModelNode.tsx
M  frontend/src/components/panels/NodeLibrary.tsx
M  frontend/src/components/panels/Toolbar.tsx
M  frontend/src/lib/graphFile.ts
M  frontend/src/store/graphStore.ts
M  frontend/src/store/uiStore.ts
M  frontend/src/styles/nodes.css
M  frontend/src/styles/panels.css
?? backend/services/chat_session.py
?? frontend/src/components/panels/ChatPanel.tsx
```

The chat panel WIP is the top candidate to finish next (pillar #3: Claude chat fluency).

### All 5 original "open decisions" now resolved

1. ✅ FAL gap report triage — all tiers done
2. ✅ Mac app v1 start signal — deferred per memory
3. ✅ Visual zones — deferred (not v1 essential)
4. ✅ Repo split for Mac app — moot (Mac deferred)
5. ✅ Runway next provider skill — shipped

---

## What's next — pick one

Under the v1 essentials frame (BYOK, nodes working, Claude chat fluency), the next moves in rough priority order:

### High-leverage (direct pillar hits)

1. **Finish the chat panel.** It's sitting uncommitted across ~13 files. Pillar #3 (Claude chat fluency) is directly blocked on getting this to a usable state. See `.planning/backlog/chat-panel-followups.md` for the v2 items deferred from the v1 build.
2. **BYOK audit end-to-end.** Every node runs through a handler that calls `get_api_key()` in `backend/services/settings.py`. Walk through each handler to confirm: (a) the key name matches what the user enters in settings UI, (b) missing-key error messages are user-friendly, (c) the settings UI actually exposes a field for every key a node requires. No one's done a full sweep.
3. **Node correctness dogfood.** 93 nodes now. How many have anyone actually run end-to-end? The gap report caught broken endpoints that no one had exercised (seedance-v1-5, wan-2-6-i2v/r2v). A matrix of "last successful run timestamp per node id" would expose more dead code before users hit it.

### Medium (useful but not blocking)

4. **Skill-table drift lint.** A quick script that reads `backend/execution/sync_runner.py`'s `endpoint_id` setdefaults and compares to the FAL `SKILL.md` routing table. Flag drift in CI. Would have caught today's bug in one test.
5. **3D mesh branch cleanup.** The branch is named `feat/3d-mesh-support` but we've been piling other stuff on top. Either merge the 3D work + rename, or split remaining 3D WIP to its own branch.
6. **Auto-layout from `.planning/backlog/chat-panel-followups.md` item #3.** Claude-created graphs stack horizontally. Medium scope. Blocks "it feels cohesive" criterion for v1.

### Low (won't help v1)

7. Helper library (color palettes, prompt templates) — parked, design spike needed
8. Drag-to-chat v2 (UUIDs + vision blocks) — parked with v1 shipped as short-ID-only
9. Visual zones — deferred
10. Mac app — deferred

---

## Decisions awaiting user input

1. **Chat panel finalization scope.** The partial implementation works; what's the bar for "done enough to commit"? Ask the user before making architectural choices.
2. **Node correctness dogfood methodology.** Manual run-through, or should we build a test harness? User preference unknown.
3. **Branch strategy.** Keep stacking on `feat/3d-mesh-support`, or start cutting separate branches per initiative?

---

## Known quirks

- **Backend needs manual restart** to pick up `node_definitions.json` changes (no hot-reload for data files).
- **Stale-output 404s** if the frontend holds a reference to an output URL past FAL's signed expiry window. Harmless but ugly.
- **FAL I2V source-image compatibility** — see commit `353ee43` and `.claude/skills/fal/skills/bytedance__seedance-2.0__fast__image-to-video.md`. Not every public URL works; WebP via v3.fal.media is the safest bet.
- **`settings.json`** is gitignored. Don't commit test API keys.
- **`.planning/private/`** is gitignored (proprietary Mac app spec etc.).

---

## Key file locations

- **Node definitions:** `backend/data/node_definitions.json` (9,370+ lines)
- **Backend handlers:** `backend/handlers/*.py` + `backend/execution/sync_runner.py` (all FAL routing lives here)
- **Frontend canvas:** `frontend/src/components/Canvas.tsx`
- **Chat panel (WIP):** `frontend/src/components/panels/ChatPanel.tsx`, `backend/services/chat_session.py`
- **Settings loader:** `backend/services/settings.py` (FAL_KEY and all API keys)
- **Settings file (gitignored):** `settings.json` at repo root
- **Skills:** `.claude/skills/{fal,meshy,gemini,runway}/`
- **Planning:** `.planning/handoff-*.md`, `.planning/fal-node-gap-report.md`, `.planning/backlog/`
- **User memory:** `~/.claude/projects/-Users-justinperea-Documents-Projects-nebula-nodes/memory/`
- **Activity log:** `~/.claude/activity/YYYY-MM-DD.log`
- **Global rules:** `~/.claude/CLAUDE.md` + `~/.claude/rules/*.md`
- **Test artifacts:** `/tmp/nebula-test/` (MP4 outputs + test scripts, wipeable)

---

## Recommended first action

Read this handoff + the previous one (`.planning/handoff-2026-04-17.md`) + the latest 5–10 entries of today's activity log:
```bash
tail -80 ~/.claude/activity/2026-04-18.log
```

Then ask the user which of the "what's next" items to start on. If they defer to judgement, start with the chat panel — it's the biggest lever for v1 pillar #3.

---

## User's working style (calibrated this session)

- Short replies preferred. Direct answers, not long summaries, unless the task inherently needs detail.
- When offered multiple paths, user picks explicitly — don't assume.
- User confirms big architectural decisions before execution ("do both" was explicit), but trusts execution details.
- Pragmatic — skipped visual zones as "not essential" once v1 framing was clear. Named the three pillars crisply.
- Likes seeing verification pass live, not just "it should work."
- Does NOT want emojis unless requested.
- Likes seeing commits happen as logical chunks, not one mega-commit.
