stock-search v1.0.0 (new) + stock-search-research v1.0.0 (new) + ltx-video-pipeline, better-search, better-search-research, deep-web-research, ai-brain-kb, ai-vid-stock updates (2026-07-22)

This commit is contained in:
Hermes Agent
2026-07-22 11:33:04 -05:00
parent c831010050
commit 7e81fdac31
8 changed files with 1265 additions and 46 deletions
+126
View File
@@ -0,0 +1,126 @@
---
name: ai-brain-kb
description: "Manage the ai_brain_kb Qdrant collection — add documents, search, and remove. Central knowledge base for all AI/ML learnings, pipeline details, and research."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux]
metadata:
hermes:
tags: [qdrant, knowledge-base, ai-brain, search, rag]
related_skills: [save-q-memory, qdrant-collection-management]
---
# AI Brain KB — Qdrant Knowledge Base Manager
Manage the `ai_brain_kb` Qdrant collection — the central knowledge base for all AI/ML learnings, pipeline details, research, and decisions.
## Storage Location
| Setting | Value |
|---------|-------|
| Qdrant | http://10.0.0.22:6333 |
| Collection | `ai_brain_kb` |
| Embedding | Ollama (snowflake-arctic-embed2) |
| MCP Tool | `mcp__better_qdrant__*` |
## What Goes Here
Everything AI/ML related that should be searchable across sessions:
- Pipeline plans, state, and architecture decisions
- Story prompts and scene descriptions
- Research results (deep research, better-search outputs)
- Model configurations, LoRA chains, render settings
- Bug diagnoses and fixes
- Stock material research
- Prompt engineering guides
- Hardware/infrastructure details for AI workloads
## Commands
### Add Documents
Add a file (markdown, text, JSON) to the knowledge base. The file is chunked and embedded automatically.
```
mcp__better_qdrant__add_documents(
collection="ai_brain_kb",
embeddingService="ollama",
filePath="/absolute/path/to/file.md"
)
```
**Chunking:** Default 500 chars with 50 char overlap. Works for .md, .txt, .json, .py files.
**After adding:** Confirm chunk count to user.
### Search
Semantic search across all knowledge in the collection.
```
mcp__better_qdrant__search(
collection="ai_brain_kb",
embeddingService="ollama",
query="your search query",
limit=10
)
```
**Tips:**
- Use natural language queries — "LTX artifact causes" not "ltx artifact"
- Results include score, title, URL (if applicable), summary, and key claims
- Higher limit = more context but more tokens
### Remove Documents
Delete individual documents by their source path (if tracked) or delete the entire collection and rebuild.
**Remove entire collection (nuclear option):**
```
mcp__better_qdrant__delete_collection(collection="ai_brain_kb")
```
**Note:** There is no per-document delete in the current MCP tool. To remove specific content, delete the collection and re-add only the files you want to keep.
### List All Collections
See what collections exist on the Qdrant instance:
```
mcp__better_qdrant__list_collections()
```
## Workflow: Save Session Learnings
After a significant session (new research, bug fix, pipeline change):
1. **Identify new/changed files** — what markdown docs were created or updated?
2. **Add to ai_brain_kb** — use `add_documents` for each file
3. **Confirm** — report chunk counts to user
4. **Clean up** — if old topic-specific collections exist, merge and delete them
## Workflow: Research a Topic
When starting work on an AI/ML topic:
1. **Search ai_brain_kb first** — what do we already know?
2. **If gaps found** — dispatch deep-research or better-search
3. **Save results** — add the research output file to ai_brain_kb
4. **Proceed** — now you have full context
## Pitfalls
- **File paths must be absolute** — the MCP tool resolves from the Hermes host filesystem.
- **Large files chunk automatically** — 500 char chunks. Very large files (100K+ chars) may produce many chunks; consider summarizing first.
- **No per-document delete** — the MCP tool only supports collection-level delete. Plan your adds accordingly.
- **Embedding model must be running** — Ollama with `snowflake-arctic-embed2` must be available on the Qdrant host (10.0.0.22:11434).
- **Collection name is exact** — `ai_brain_kb`, not `ai-brain-kb` or `ai_brain`.
- **Search is semantic, not keyword** — phrase queries naturally. "How to fix LTX artifacts" works better than "ltx artifact fix".
- **Don't create topic-specific collections** — everything goes into `ai_brain_kb`. The user's rule: one brain, one collection.
## Related Skills
- `save-q-memory` — Manual save to the `memories` collection (personal/behavioral memory, not knowledge base)
- `qdrant-collection-management` — Collection-level operations: consolidation, migration, dedup, registry
+149
View File
@@ -0,0 +1,149 @@
---
name: ai-vid-stock
description: "Manage AI video stock materials on TrueNAS — add, search, list, and remove start frames, audio, character refs, and misc images."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux]
metadata:
hermes:
tags: [ai-video, stock-materials, truenas, smb, ltx, comfyui]
---
# AI Video Stock Material Manager
Manage stock materials for the LTX video pipeline stored on TrueNAS at `10.0.0.117`.
## Storage Location
| Setting | Value |
|---------|-------|
| Server | 10.0.0.117 (TrueNAS) |
| Share | proxmoxBackup (read-write, guest access) |
| Root path | `ai_vid_stock_material/` |
| Access | `smbclient -N //10.0.0.117/proxmoxBackup` |
## Directory Structure
```
ai_vid_stock_material/
├── README.md ← inventory (keep updated)
├── start_frames/ ← first/last frame images for I2V
├── audio/ ← TTS clips, ambient sounds, music
├── character_refs/ ← character reference images for ID LoRA
├── misc_images/ ← unsorted images, potential stock
├── scripts/ ← generation scripts, prompt templates
├── workflows/ ← ComfyUI workflow JSONs
├── outputs/ ← rendered videos (concat finals)
└── docs/ ← plans, state docs, story ideas
```
## Commands
### List all stock materials
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material; ls start_frames/*; ls audio/*; ls character_refs/*; ls misc_images/*; ls scripts/*; ls workflows/*'
```
### List a specific category
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material; ls <category>/*'
```
Categories: `start_frames`, `audio`, `character_refs`, `misc_images`, `scripts`, `workflows`
### Search by filename pattern
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material; ls start_frames/*' 2>/dev/null | grep -i "<pattern>"
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material; ls audio/*' 2>/dev/null | grep -i "<pattern>"
# ... repeat for each category
```
### Add a file (upload)
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material/<category>; put <local_path> <remote_filename>'
```
Example:
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material/start_frames; put /tmp/new_frame.png scene_07_start.png'
```
### Add from remote server (e.g., .202 ComfyUI)
```bash
# 1. Download from remote
sshpass -p 'passw0rd' scp [email protected]:~/comfy-ui/input/<filename> /tmp/
# 2. Upload to TrueNAS
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material/<category>; put /tmp/<filename> <filename>'
```
### Remove a file
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material/<category>; rm <filename>'
```
### Download a file from stock
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material/<category>; get <filename> <local_path>'
```
### Download entire category
```bash
mkdir -p /tmp/stock_dl/<category>
cd /tmp/stock_dl/<category>
smbclient -N //10.0.0.117/proxmoxBackup -c "cd ai_vid_stock_material/<category>; prompt OFF; mget *"
```
### Update README inventory after changes
After adding/removing files, update the README.md on TrueNAS:
```bash
# Download current README
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material; get README.md /tmp/README.md'
# Edit /tmp/README.md to reflect changes
# Upload updated README
smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material; put /tmp/README.md README.md'
```
## Category Guidelines
| Category | What goes here | File types |
|----------|---------------|------------|
| start_frames | First/last frame images for I2V generation | .png, .jpg |
| audio | TTS clips, ambient sounds, music for video | .mp3, .wav |
| character_refs | Reference images for ID LoRA character consistency | .png, .jpg |
| misc_images | Unsorted images, potential stock, inspiration | .png, .jpg |
| scripts | Generation scripts, prompt templates, automation | .py, .sh, .json, .txt |
| workflows | ComfyUI workflow JSONs (exported from UI) | .json |
## Pitfalls
- **SMB path separators are backslashes** — use `cd ai_vid_stock_material\\start_frames` in smbclient, not forward slashes.
- **No mount available** — the cifs kernel module is not present on the Hermes host. Use smbclient for all operations. Do not attempt `mount.cifs`.
- **smbclient `mget`/`mput` need `prompt OFF`** — otherwise it prompts for every file.
- **Spaces in filenames** — quote them in smbclient commands.
- **Keep README.md updated** — it's the inventory of record. After any add/remove, update it.
- **TrueNAS guest access** — no credentials needed. If auth errors appear, the share config may have changed.
- **Large files** — smbclient `put`/`get` works for files up to several GB. For bulk transfers, consider using the TrueNAS web UI at `http://10.0.0.117`.
## LTX Pipeline Wiring Bug (2026-07-21)
**Symptom:** Subject duplication in LTX Director renders — a frozen duplicate of the start frame appears alongside the generated motion. All outputs are 249 frames instead of 240.
**Root cause:** Node 132 (LTXDirectorGuide refiner) takes its `latent` input from the uncropped stage-1 output (`["34", 0]`) instead of the cropped output (`["55", 2]`). The guide frames from stage 1 leak through as actual video.
**Fix:** Point `132.inputs.latent` at `["55", 2]` instead of `["34", 0]`. Verify output is exactly 240 frames.
**Reference:** `/home/n8n/workspace/general/ltx-pipeline-state.md` — full render history and diagnosis.
+20 -4
View File
@@ -1,7 +1,7 @@
--- ---
name: better-search-research name: better-search-research
description: Medium-depth web research methodology — 3-move flow (initial search → AI evaluation → condense), 3-loop cap, /tmp ledger, file-only delivery. Opt-in skill for the research profile. description: Medium-depth web research methodology — 3-move flow (initial search → AI evaluation → condense), 3-loop cap, /tmp ledger, file-only delivery. Opt-in skill for the research profile.
version: 1.0.1 version: 1.1.0
author: Hermes Agent author: Hermes Agent
metadata: metadata:
hermes: hermes:
@@ -69,9 +69,25 @@ No credibility tier — the ledger is just URL + key facts + date. Tier judgment
happens in the body, not the ledger. happens in the body, not the ledger.
**SearXNG error handling:** If `mcp_searxng_searxng_web_search` returns 0 **SearXNG error handling:** If `mcp_searxng_searxng_web_search` returns 0
results or errors, count it as one search and either retry once with a different results or errors:
framing or proceed to Move 3 with what was found. Don't burn a refinement slot
on retries. 1. **First failure:** Reconnect VPN to get a fresh IP, then retry the SAME
search once. The VPN reconnect procedure is:
```bash
nordvpn disconnect && nordvpn connect us <different_city>
```
Use a different city from the current connection to avoid the same server.
Verify with `nordvpn status`. This is authorized without asking — the
nordvpn skill grants reconnect permission. Do NOT change any other VPN
settings.
2. **Second failure (after VPN reconnect):** Retry once with a different
framing (different keywords, category, or time_range).
3. **Third failure:** Proceed to Move 3 with what was found. Don't burn a
refinement slot on retries.
Count each search attempt (including retries) toward the total. The VPN
reconnect is a recovery step, not a search — it doesn't count against the
3-loop cap.
**Filesystem assumption:** `mkdir -p ~/workspace/research/results` and all `~` **Filesystem assumption:** `mkdir -p ~/workspace/research/results` and all `~`
paths in Move 3 assume the research profile shares the same filesystem as the paths in Move 3 assume the research profile shares the same filesystem as the
+48 -9
View File
@@ -1,7 +1,7 @@
--- ---
name: better-search name: better-search
description: Medium-depth web research dispatcher — delegates to the research profile for a 3-move search flow (initial search → AI evaluation → condense). File-only delivery. Trigger phrases: "better search", "do a better search". description: 'Medium-depth web research dispatcher — delegates to the research profile for a 3-move search flow (initial search → AI evaluation → condense). File-only delivery. Trigger phrases: "better search", "do a better search".'
version: 1.0.1 version: 1.1.0
author: Hermes Agent author: Hermes Agent
metadata: metadata:
hermes: hermes:
@@ -107,6 +107,38 @@ The research agent writes the result file to
`~/workspace/research/results/<YYYY-MM-DD>-<slug>.md`. The operator reads it `~/workspace/research/results/<YYYY-MM-DD>-<slug>.md`. The operator reads it
with `cat` or their preferred reader. with `cat` or their preferred reader.
### Variant: agent needs the results itself (multi-step research chains)
The §5 default is fire-and-forget — the operator reads the file. But when the
*agent* needs the research output to feed a downstream step (e.g. collecting
3 layer-research files, then sending the digest to Claude for adversarial
review), the agent must collect the results itself. Pattern (used successfully
2026-07-07 for a 3-layer AI-video landscape research chain):
1. **Dispatch each question as a background terminal process** with
`notify_on_complete=true`. One question per dispatch (the 3-loop cap is
per-dispatch). Run them in parallel — they're independent.
```bash
terminal(background=true, notify_on_complete=true,
command="cd ~/workspace/research && hermes -p research -s better-search-research chat -q \"<question>\" -Q --max-turns 50 --yolo 2>&1 | tail -5")
```
2. **Wait for each to finish** via `process(action='wait', session_id=...)`.
The `tail -5` keeps stdout small — the real deliverable is the result file,
not the terminal output. Capture the `session_id` from the final stdout
line for the operator's reference.
3. **Read the result files** from `~/workspace/research/results/` with
`read_file` (sorted by mtime: `ls -t ~/workspace/research/results/ | head`).
The files are the authoritative output — the terminal stdout is just a
summary + session_id.
4. **Proceed with the downstream step** (digest, Claude review, plan-writing)
using the file contents.
This variant does NOT violate the no-poll/no-background rule (§7 pitfall 4) —
that rule is about not stranding the *operator* with a pending research job
they have to babysit. When the agent is the consumer and is actively working
the chain, background dispatch + wait is correct. The fire-and-forget rule
still applies when the operator is the audience.
## §6 No-Resume Rule ## §6 No-Resume Rule
**No `--resume`.** The dispatcher reports `session_id` for the operator's **No `--resume`.** The dispatcher reports `session_id` for the operator's
@@ -135,7 +167,9 @@ iterative drilling on the same evidence matters, use `deep-research` instead
to the operator immediately after capturing the session_id. It does NOT run to the operator immediately after capturing the session_id. It does NOT run
the research in the background, does NOT periodically check whether the the research in the background, does NOT periodically check whether the
result file has appeared, and does NOT auto-deliver the result inline or to a result file has appeared, and does NOT auto-deliver the result inline or to a
chat platform. chat platform. (Exception: the agent-needs-results variant in §5 — when the
agent is the consumer and actively working a multi-step chain, background
dispatch + wait is correct.)
5. **Max 3 clarifying questions (see §4).** Multi-part questions get condensed 5. **Max 3 clarifying questions (see §4).** Multi-part questions get condensed
into a single noun-phrase question or split into separate dispatches. into a single noun-phrase question or split into separate dispatches.
@@ -149,12 +183,15 @@ iterative drilling on the same evidence matters, use `deep-research` instead
other ordinary English — they collide with normal agent tasks on dev/code other ordinary English — they collide with normal agent tasks on dev/code
profiles. profiles.
8. **Do NOT second-guess the dispatch command.** The command `research -s 8. **The `-p` flag exists. Do NOT hallucinate that it doesn't.** Some models
better-search-research chat -q "..." -Q --max-turns 50 --yolo` is verified (observed: minimax-m3:cloud) read the dispatch command, decide `-p` is a
and correct. `research` is a profile alias at `~/.local/bin/research` — it "wrong flag," and fall back to running the search themselves with SearXNG
works from any directory. Do NOT assume it doesn't exist and fall back to MCP — bypassing the entire dispatcher. This is a hallucination. `hermes -p
doing the search yourself. The dispatcher's ONLY job is to run this command <profile>` is a standard Hermes CLI feature. If you're unsure, run `hermes
and report the session_id — never substitute your own search. --help` to verify — do NOT assume the command is wrong and silently
substitute your own approach. The dispatcher MUST run the command as
written in §3. If the command fails, report the actual error — don't
fabricate a reason not to run it.
## §8 See Also ## §8 See Also
@@ -164,3 +201,5 @@ iterative drilling on the same evidence matters, use `deep-research` instead
Use for quick factual lookups. Use for quick factual lookups.
- `ask-hermes` — persistent peer Hermes agent for delegated work. Use for - `ask-hermes` — persistent peer Hermes agent for delegated work. Use for
general-purpose delegation, not research-specific flows. general-purpose delegation, not research-specific flows.
- `nordvpn` — VPN management. The methodology skill auto-reconnects VPN on
SearXNG engine failure to get a fresh IP before retrying.
+83 -33
View File
@@ -1,7 +1,7 @@
--- ---
name: deep-web-research name: deep-web-research
description: Exhaustive deep web research — six-move flow, external findings ledger, mechanical saturation check, disconfirmation, condensation from disk. Domain-aware tool selection with adaptive re-strategizing. Opt-in skill for the research profile. description: Exhaustive deep web research — six-move flow, external findings ledger, mechanical saturation check, disconfirmation, condensation from disk. Domain-aware tool selection with adaptive re-strategizing. Opt-in skill for the research profile.
version: 2.1.0 version: 2.6.0
author: Hermes Agent author: Hermes Agent
--- ---
@@ -15,7 +15,7 @@ exhaustive research methodology.
These persist across all turns — they are in the skill, not in fading context: These persist across all turns — they are in the skill, not in fading context:
- **Confined to /tmp.** All file writes go to `/tmp/`. Never write outside /tmp. - **Confined to /tmp.** All file writes go to `/tmp/`. Never write outside /tmp. **Exception:** The final condensed report (Move 5) and the abort report (Under-Specified Question Handling) go to `/home/n8n/workspace/research/results/` (absolute path, create the directory first with `mkdir -p`). Also, any file path the operator names explicitly in the prompt (e.g., Stage 3 fix pass editing a plan file in place). The ledger and gate files stay in /tmp.
- **No self-provisioning.** Never install software. No pip, npm, apt, docker, or - **No self-provisioning.** Never install software. No pip, npm, apt, docker, or
any package manager. Use only what's already configured. any package manager. Use only what's already configured.
- **No repeat searches.** If you catch yourself searching the same thing twice, - **No repeat searches.** If you catch yourself searching the same thing twice,
@@ -66,7 +66,7 @@ static reference, not generated per-question.
At 600 turns, early findings scroll out of context. The ledger is the fix. At 600 turns, early findings scroll out of context. The ledger is the fix.
**Path:** `/tmp/research-<session-id>.md` **Path:** `/tmp/research-<YYYY-MM-DD>-<slug>.md` (see Move 0 — the stem is picked once, not derived from session_id)
**Schema per finding:** **Schema per finding:**
``` ```
@@ -114,9 +114,21 @@ This skill runs headless — there is no operator to ask clarifying questions. I
**What to do instead of guessing:** **What to do instead of guessing:**
1. Do NOT start Move 0. Do NOT begin the ledger. 1. Do NOT start Move 0. Do NOT begin the ledger.
2. Write to stderr / final report: 2. Write the abort report to the results path so the dispatcher can find it:
``` ```
mkdir -p /home/n8n/workspace/research/results
```
Then write to `/home/n8n/workspace/research/results/<YYYY-MM-DD>-<slug>-ABORTED.md`:
```
---
question: "<original question>"
date: <YYYY-MM-DD>
status: ABORTED
---
## Aborted: Under-Specified Question ## Aborted: Under-Specified Question
The question "<original question>" has multiple plausible interpretations. The question "<original question>" has multiple plausible interpretations.
@@ -140,6 +152,8 @@ This skill runs headless — there is no operator to ask clarifying questions. I
### Move 0: Analyze & Strategize ### Move 0: Analyze & Strategize
**Pick the ledger stem once:** `/tmp/research-<YYYY-MM-DD>-<slug>`. Use `<stem>.md` for the ledger and `<stem>-gate.md` for the gate. Substitute this stem into every grep below. (The session_id is not available to the agent under `-Q` — use the date+slug stem instead.)
1. Consult the `search-key` decision matrix — it's your tool reference, not a 1. Consult the `search-key` decision matrix — it's your tool reference, not a
lookup you match against. lookup you match against.
@@ -156,7 +170,9 @@ This skill runs headless — there is no operator to ask clarifying questions. I
- Pivots: if I find <X>, add <tool Y> - Pivots: if I find <X>, add <tool Y>
``` ```
4. OSINT gate — only if the plan names maigret / holehe / theHarvester / 4. Write the phase gate template (see Guardrails → Phase Gate) to `<stem>-gate.md` with all boxes unchecked. This is the starting state — update it as you progress.
5. OSINT gate — only if the plan names maigret / holehe / theHarvester /
Spiderfoot AND the target is a private individual with no public role: log Spiderfoot AND the target is a private individual with no public role: log
`## Ethics Note: <intent>` and confirm the scan is proportionate. `## Ethics Note: <intent>` and confirm the scan is proportionate.
@@ -247,11 +263,37 @@ Disconfirmation actively hunts for disagreement.
### Move 5: Condensation ### Move 5: Condensation
Read the full ledger from disk. Read the phase gate file. If any box is Read the full ledger from disk. Read the phase gate file. If any box is
unchecked, do NOT condense — go back and complete that item. unchecked, do NOT condense — go back and complete that item. (The `OR:` items
in the gate are alternatives, not requirements — a normal run will have some
unchecked; that's expected.) **Exception: the turn-ceiling ramp overrides the
gate. At ≥450 turns (once the ramp has fired), condense regardless of unchecked
boxes and list the unmet gate items under `## Uncertainty`.**
Synthesize using this template: Synthesize using this template, then **WRITE the report to disk**:
1. `mkdir -p /home/n8n/workspace/research/results`
2. Write to `/home/n8n/workspace/research/results/<YYYY-MM-DD>-<slug>.md` (absolute path, derive slug from the question)
This is the single deliverable — the dispatcher expects it at this path. Do NOT just output to stdout and exit.
3. **Save to ai_brain_kb.** After writing the report, add it to the Qdrant knowledge base:
```
mcp__better_qdrant__add_documents(
collection="ai_brain_kb",
embeddingService="ollama",
filePath="/home/n8n/workspace/research/results/<YYYY-MM-DD>-<slug>.md"
)
```
This is mandatory — every deep research report goes into the brain. The `ai-brain-kb` skill and `better_qdrant` MCP server are configured on this profile. If the MCP call fails (network, Qdrant down), log the error to the report's Uncertainty section and continue — the report file on disk is the source of truth.
``` ```
---
question: "<original question>"
date: <YYYY-MM-DD>
sources: <count>
confidence: <high|medium|low>
---
# <Answer in 1-3 sentences> # <Answer in 1-3 sentences>
## Key Findings ## Key Findings
@@ -273,7 +315,7 @@ Synthesize using this template:
## Tools That Would Have Helped ## Tools That Would Have Helped
- <tool>: <what it would have enabled> - <tool>: <what it would have enabled>
None: all sources were accessible with available tools. (If nothing was missing, write exactly: "None: all sources were accessible with available tools.")
``` ```
## Guardrails ## Guardrails
@@ -282,22 +324,24 @@ None: all sources were accessible with available tools.
Every 3-4 searches, run this command — do not self-assess: Every 3-4 searches, run this command — do not self-assess:
``` ```
grep -c "^### Finding #.*\[SQ<N>\]" /tmp/research-<sid>.md grep -c "^### Finding #.*\[SQ<N>\]" /tmp/research-<YYYY-MM-DD>-<slug>.md
``` ```
Compare to the previous count. If zero new findings in the last 3 searches, Compare to the previous count. If zero new findings in the last 3 searches,
that sub-question is saturated. Move to the next. This is a measurable fact, that sub-question is saturated. Move to the next. **Exception: if the count is
not a vibe. The `[SQ<N>]` tag makes this immune to header ordering — it counts 0 (no findings at all), keep going to 5 searches, then document it with the
by tag, not by position. information-void template.** This is a measurable fact, not a vibe. The `[SQ<N>]`
tag makes this immune to header ordering — it counts by tag, not by position.
### Phase Gate File ### Phase Gate File
The phase gate is a file at `/tmp/research-<sid>-gate.md`. Write it and read it The phase gate is a file at `/tmp/research-<YYYY-MM-DD>-<slug>-gate.md`. Write it and read it
back — it is not a mental checklist. Before moving to Move 5, read the gate file. back — it is not a mental checklist. Before moving to Move 5, read the gate file.
If any box is unchecked, do NOT condense. Go back and complete that item. (The `OR:` items are alternatives, not requirements — a normal run will have some
unchecked; that's expected.)
``` ```
# Phase Gate # Phase Gate
- [ ] All sub-questions have findings in the ledger - [ ] All sub-questions have findings in the ledger or are documented as VOID
- [ ] Disconfirmation pass completed for key claims - [ ] Disconfirmation pass completed for key claims
- [ ] Source diversity: ≥5 unique domains across all findings - [ ] Source diversity: ≥5 unique domains across all findings
- [ ] Source diversity: no single domain >30% of findings - [ ] Source diversity: no single domain >30% of findings
@@ -311,8 +355,9 @@ Update this file as you progress.
Mechanical domain diversity check: Mechanical domain diversity check:
``` ```
grep -oP 'Source: \K[^ ]+' /tmp/research-<sid>.md | grep -oP 'https?://[^/]+' | sort -u | wc -l grep -oP 'Source: \K[^ ]+' /tmp/research-<YYYY-MM-DD>-<slug>.md | grep -oP 'https?://[^/]+' | sort | uniq -c | sort -rn
``` ```
This shows both the unique domain count and the per-domain share — use it to verify the ≥5 domains and ≤30% per-domain requirements.
### Turn Ceiling ### Turn Ceiling
@@ -324,9 +369,26 @@ If the ceiling is hit, deliver partial findings with a note on what's missing.
### SearXNG Failure Handling ### SearXNG Failure Handling
If SearXNG returns errors or empty results for 3 consecutive searches (different If SearXNG returns errors or empty results for 3 consecutive searches (different
queries), wait 10 seconds and retry once. If still failing, note the instance queries):
issue in the ledger and fall back to `web_search` (built-in) or
`duckduckgo-search` (Python library) for the remainder of that sub-question. 1. **First recovery: VPN reconnect.** Reconnect VPN to get a fresh IP, then
retry the most recent search once. The VPN reconnect procedure is:
```bash
nordvpn disconnect && nordvpn connect us <different_city>
```
Use a different city from the current connection to avoid the same server.
Verify with `nordvpn status`. This is authorized without asking — the
nordvpn skill grants reconnect permission. Do NOT change any other VPN
settings.
2. **Second recovery:** Wait 10 seconds and retry once with a different
framing.
3. **Third recovery:** Fall back to `web_search` (built-in), or
`duckduckgo-search` (Python library) if already installed.
4. **If all fail:** Document the void per the information-void template and
move on.
The VPN reconnect is a recovery step, not a search — it doesn't count against
the turn budget or saturation tracking.
## Tool Policy ## Tool Policy
@@ -336,17 +398,5 @@ APIs with billing, no metered endpoints. You determine what fits — you are not
given a list of allowed or disallowed tools. given a list of allowed or disallowed tools.
**No self-provisioning.** Never install, pull, or spin up new tools at runtime. **No self-provisioning.** Never install, pull, or spin up new tools at runtime.
(The "Tools That Would Have Helped" section in the Move 5 report template covers
### Tools That Would Have Helped tool gaps — it's informational only; do not stop or block on them.)
At the end of the response (after Sources), add a section if any limitations
were hit:
```
Tools that would have improved this research:
- <tool name>: <what it would have enabled>
None: all sources were accessible with available tools.
```
This is informational only. Do your best with what's available and note what
could have been better. Do not stop or block on tool gaps.
+510
View File
@@ -0,0 +1,510 @@
---
name: ltx-video-pipeline
description: "LTX Video pipeline on 10.0.0.202 — model chain wiring, render settings, concat, stock management, and Transition LoRA multi-scene workflows."
version: 2.0.0
author: Hermes Agent
license: MIT
platforms: [linux]
metadata:
hermes:
tags: [ltx, video, comfyui, pipeline, ai-video, transition-lora]
related_skills: [ai-vid-stock, truenas, better-search]
---
# LTX Video Pipeline
End-to-end LTX Video pipeline on the ComfyUI LXC at 10.0.0.202.
## Environment
| Setting | Value |
|---------|-------|
| Target | 10.0.0.202 (Proxmox LXC 9009) |
| SSH | `sshpass -p 'passw0rd' ssh [email protected]` |
| ComfyUI | port 8188, venv ~/comfy-env, install ~/comfy-ui/ |
| GPU | RTX 4090 24GB VRAM |
| ffmpeg | /usr/bin/ffmpeg (7.1.5) |
| State file | `~/workspace/general/ltx-pipeline-state.md` |
| Continue file | `~/workspace/general/ltx-video-pipeline-continue.md` |
| Plan file | `~/workspace/general/ltx-pipeline-plan.md` |
## Model Chain
### DEFAULT: Single-Stage I2V (fp8 + TenStrip cond-safe or Distilled, NO ID LoRA) — USE THIS FOR ALL SCENES
**The 6 fixes from deep research (2026-07-22, 15 sources, v2 correction) are the baseline.** The 2-clip test confirmed: single-stage 18 steps, guide_strength 1.0, no ID LoRA, 768×512, simplified prompts — clean 241-frame output, no Director wiring bug.
**⚠️ Fix #5 (Distilled LoRA 1.0) was CORRECTED by follow-up deep research (2026-07-22, 15 sources).** Community consensus: Distilled LoRA at 1.0 causes quality degradation for I2V. The correct range is 0.5-0.7. The confusion was conflating two different parameters: I2V conditioning strength (guide_strength, should be 1.0) vs Distilled LoRA strength (should be 0.5-0.7). Sources: aistudynow.com ("Do not set the strength to 1.0"), official ComfyUI guide (uses 0.5), TenStrip experiments ("The official rank 384 LoRA can actively work against conditioned inputs").
**PREFERRED: TenStrip cond-safe LoRA (rank-72, 662 MB) at strength 1.0.** This is purpose-built for I2V — zeroes out cross-attention bridges, adaln/scale-shift tables, gate logits, and prompt scale-shift that fight I2V conditioning. "This is technically what an official I2V distilled lora should have had." Download from huggingface.co/TenStrip/LTX2.3_Distilled_Lora_1.1_Experiments — file: `ltx-2.3-22b-distilled-lora-1.1_fro90_ceil72_condsafe.safetensors`. Safe at 1.0 on first pass I2V. Upscale pass at 0.4.
**FALLBACK: Official Distilled LoRA (rank-384, 7.1 GB) at strength 0.5-0.7.** Use only if TenStrip cond-safe is not available. The official LoRA's cross-attention bridges actively fight I2V conditioning — do NOT use at 1.0.
```
UNETLoader (fp8 distilled transformer)
→ LTX2LoraLoaderAdvanced (TenStrip cond-safe rank-72, strength 1.0) ← PREFERRED
→ LTX2LoraLoaderAdvanced (distilled-lora-384-1.1, strength 0.5-0.7) ← FALLBACK
→ LTXDirector (single-stage, 16-20 steps)
```
**Why this chain:**
- **TenStrip cond-safe at 1.0** — purpose-built for I2V, zeroes out conditioning-fighting layers. Safe at full strength.
- **NO ID LoRA** — TalkVid-3K is trained for talking-head footage, not action scenes or camera pans. It adds frontal-face bias with no upside. Drop it for ALL scenes unless doing a dedicated talking-head video.
- **Single-stage (16-20 steps)** — the two-stage refiner (4 steps at denoise 0.42) may be smearing, not refining. Single-stage at 18 steps produced clean output in the 2-clip test.
- **guide_strength 1.0** — I2V conditioning at 1.0 anchors the start frame properly. The old 0.5 was too weak, causing identity drift. The old "DO NOT use 1.0" rule was based on v4 failures where ID LoRA was ALSO at 1.0 — the duplication was from stacked LoRA interference, not from guide_strength alone. With ID LoRA dropped, guide_strength 1.0 is clean.
**ID LoRA drop rule (when keeping it for talking-head only):** Rewire node 131's `model` input from `["201", 0]` to `["200", 0]` and delete node 201.
**Full two-stage → single-stage transformation recipe:** See `references/workflow-transformation-two-to-single-stage.md` — complete node deletion list (9 nodes), rewiring table (6 connections), settings changes, timeline data updates, and verification checklist. 31 nodes → 22 nodes. First applied 2026-07-22 on the 2-clip test.
### DEPRECATED: Two-Stage I2V (fp8 + Distilled + ID) — v4/v5 era
```
UNETLoader (fp8 distilled transformer)
→ LTX2LoraLoaderAdvanced (distilled-lora-384-1.1, strength 0.7)
→ LTX2LoraLoaderAdvanced (id-lora-talkvid-3k, strength 0.6)
→ LTXDirector (two-stage: 8+4 steps)
```
**Do not use this chain for new work.** It produced artifacts in v4 and v5. Kept for reference only.
### Transition/Morph Scenes ONLY (fp8 + Transition + Distilled + ID)
```
UNETLoader (fp8 distilled transformer)
→ LoraLoaderModelOnly (ltx2.3-transition.safetensors, strength 1.0)
→ LTX2LoraLoaderAdvanced (distilled-lora-384-1.1, strength 0.7)
→ LTX2LoraLoaderAdvanced (id-lora-talkvid-3k, strength 0.6)
→ LTXDirector
```
**CRITICAL: Do NOT use the Transition LoRA chain for standard I2V scenes.** The Transition LoRA forces transformation/morphing behavior even without the `zhuanchang` trigger word. On standard I2V, it causes subject duplication and wrong-scene hallucination (confirmed: man getting out of bed split into two; kitchen scene became man+soup). Only use it for actual scene-to-scene morphing, identity transformations, or style changes.
**Transition LoRA uses standard `LoraLoaderModelOnly`, NOT `LTX2LoraLoaderAdvanced`.** It must be the FIRST LoRA in the chain (closest to UNETLoader).
## CRITICAL: Director Wiring Bug (Node 132 Latent Input)
**This bug caused 3 failed render batches (2026-07-21).** Subject duplication persisted across all settings changes because the wiring was wrong.
### The Bug
Node 132 (LTXDirectorGuide, the refiner pass) takes its `latent` input from the **uncropped** stage-1 output (`["34", 0]` — LTXVSeparateAVLatent) instead of the **cropped** output (`["55", 2]` — LTXDirectorCropGuides).
LTXDirectorGuide appends guide frames as extra latent frames, then records how many to remove. LTXDirectorCropGuides trims them. But if the refiner takes the uncropped latent, the guide frames leak through as actual video — a frozen duplicate of the subject.
### Verification
**Correct output: 240-241 frames for 10s@24fps.** The Director may produce 241 due to a 1-frame rounding quirk — this is normal. If ffprobe shows 249 frames, the bug is present (guide frames leaked). All 3 failed batches produced 249 frames; v4 success produced 241.
### The Fix
In every scene JSON, ensure:
```json
"132": {
"inputs": {
"latent": ["55", 2] // NOT ["34", 0]
}
}
```
### How It Was Found
Claude Opus SSH'd into 10.0.0.202, read the workflow JSON, read the LTXDirectorGuide source code (`ltx_director_guide.py`), checked ffprobe frame counts, and compared against the shipped reference workflow. Full diagnosis in `references/claude-wiring-diagnosis-2026-07-21.md`.
| Setting | Value | Notes |
|---------|-------|-------|
| Resolution | 768×512 | LTX trained for widescreen; 512×512 is suboptimal |
| FPS | 24 | Standard cinematic |
| Duration | 5s (121 frames) for testing, 10s (241 frames) for final | Test at 5s first — temporal coherence degrades after 5-6s |
| Sampler | euler | |
| Scheduler | **simple** | NOT linear_quadratic — distilled model is fragile with non-standard schedules |
| Steps | 16-20 single-stage | No refiner. Two-stage (8+4) may smear, not refine |
| CFG | 1.0 | Distilled model — do NOT raise for standard scenes |
| guide_strength | **1.0** | Confirmed clean in 2-clip test (2026-07-22). The old "DO NOT use 1.0" rule was from v4 where ID LoRA was also at 1.0 — the duplication was stacked LoRA interference, not guide_strength alone. With ID LoRA dropped, 1.0 is clean. |
| Distilled LoRA | **TenStrip cond-safe 1.0** (preferred) or **official 0.5-0.7** (fallback) | Official LoRA at 1.0 degrades I2V quality — use TenStrip cond-safe instead |
| ID LoRA | **Dropped** | TalkVid-3K is talking-head only; drop for all non-talking scenes |
| Peak VRAM | ~23.5GB / 24GB | |
### guide_strength — RESOLVED (2026-07-22)
**Use 1.0.** The 2-clip test confirmed: guide_strength 1.0 is clean with ID LoRA dropped. The old "DO NOT use 1.0" rule was based on v4 failures where ID LoRA was ALSO at 1.0 — the duplication was from stacked LoRA interference, not from guide_strength alone. With ID LoRA dropped, 1.0 is the correct value for proper I2V start-frame anchoring.
From the LTX Director GitHub issue #258: "Hard pin = velocity discontinuity. When a pin lands where motion is active, the static frame overrides motion mid-stream → snap." This applies when guide_strength is combined with other strong conditioning (ID LoRA, Transition LoRA). With a clean single-LoRA chain, 1.0 is safe.
**Verification:** After rendering, check the actual guide_strength used by extracting metadata:
```bash
ffprobe -v quiet -show_entries format_tags=prompt output.mp4 | grep -oP 'guide_strength.*?(\d+\.?\d*)'
```
### CFG Per Scene Type
| Scene Type | CFG | Notes |
|------------|-----|-------|
| Standard I2V (distilled) | 1.0 | Do NOT raise |
| Transition LoRA scenes | 4.0 | Required for zhuanchang to activate properly |
## Prompting Rules (CRITICAL — session 2026-07-21)
LTX-2.3 needs detailed, structured prompts. Short 1-2 sentence prompts produce bad output: subject duplication, wrong scenes entirely, static camera, identity drift, unnatural motion, flickering. The user confirmed: "I watched the video, it worked but it's all messed up. I think the issue is the prompts."
**Two confirmed failure modes from our renders:**
1. **Subject duplication** — "The man getting out of bed split into two men. One got out of bed and he was still in bed at the same time." Root cause: `guide_strength: 1.0` (hard pin) + no camera direction + no motion detail.
2. **Wrong scene entirely** — "Scene two was a man and a woman, he was scooping soup." Root cause: `zhuanchang` on a non-transition scene + prompt too short (15 words). The model filled gaps with random kitchen training data.
### Required Elements in Every Prompt
1. **Shot description** — close-up, medium shot, wide shot, low angle, tracking shot, overhead, POV
2. **Camera movement** — dolly in/out, pan left/right, tilt up/down, zoom, tracking, static, handheld, crane, Steadicam
3. **Subject action** — detailed motion: gait, speed, gestures, facial expression changes, body language. Present tense. Sequential.
4. **Environment detail** — lighting (golden hour, overcast, neon, soft studio, morning sunlight, dusk), textures, atmosphere, weather
5. **Temporal flow** — what happens first, then what changes, how the scene evolves over the 10 seconds
6. **Audio** — ambient sounds, specific SFX, music, dialogue in quotes
### Prompt Order
```
Shot + Camera → Subject + Action → Lighting + Environment → Audio + Mood
```
### Transition LoRA (`zhuanchang`)
- **Trigger word:** `zhuanchang` — append to END of prompt
- **When to use:** ONLY on scenes that involve a transformation, morph, or scene transition (present→memory, reality→vision, character morph, style change, environment transition)
- **When NOT to use:** Standard single-scene I2V shots with no transformation. Using it on every scene forces the model to try to morph when it shouldn't — this causes flickering, identity drift, and hallucinated content (confirmed: man+soup scene).
- **Strength:** 1.0
- **CFG:** 4.0 (NOT 1.0 — Transition LoRA needs higher CFG)
### Prompt Template (Standard I2V — no zhuanchang)
```
[Shot type and camera language]. [Subject and scene description].
[Describe the action in sequence over the full duration — what happens first, then what changes].
[Lighting, texture, atmosphere, composition cues]. [Audio description].
```
### Prompt Template (Transition Scene — with zhuanchang)
```
[Shot type and camera language]. [Subject and scene description].
[Describe the motion, transformation, or transition process in detail — how one state morphs into another].
[Lighting, texture, atmosphere, and composition cues]. zhuanchang
```
### Example: Bad vs Good Prompt
**Bad (what we used — produced messed up output):**
> A man wakes up in a small cabin bedroom, morning sunlight streaming through the window. He sits up slowly, rubbing his eyes., zhuanchang
**Problems:** No camera direction, no shot framing, no motion detail, no temporal flow, no audio, zhuanchang on a non-transition scene, only 25 words.
**Good (with camera, shot, motion, temporal flow, audio):**
> Medium shot, static camera. A man in his 30s lies in a rustic cabin bed, morning sunlight streaming through a window casting warm golden light across rumpled sheets. Over 10 seconds: he stirs, eyes slowly opening, then pushes himself up to sitting, rubbing his eyes with both hands. He blinks, adjusting to the light, then looks toward the window with a calm expression. Warm golden hour light, dust motes floating in sunbeams, wooden cabin interior with exposed log walls. Birds chirping outside, soft rustle of bedsheets. Photorealistic, 35mm film, shallow depth of field.
**What changed:** Added shot framing, camera type, sequential action over time, lighting detail, environment texture, audio, removed zhuanchang. 80 words vs 25.
## Artifact Prevention (DEEP RESEARCH — 2026-07-22, 18 sources)
The 7 fixes below supersede the old 6-agent review (2026-07-21). These are the new defaults.
### The 6 Fixes (ranked by impact, v2 corrected 2026-07-22)
| # | Fix | From | To | Why |
|---|-----|------|----|-----|
| 1 | ID LoRA | TalkVid-3K (talking-head) | Drop entirely | Trained for static faces, fights against action motion |
| 2 | I2V conditioning | 0.5 | 1.0 | Too weak to anchor start frame — causes identity drift |
| 3 | Stages | Two-stage (8+4 refiner) | Single-stage (16-20 steps) | Refiner may be smearing, not refining |
| 4 | Resolution | 512×512 | 768×512 | LTX trained for widescreen, square is suboptimal |
| 5 | Distilled LoRA | Official 384 @ 1.0 | **TenStrip cond-safe @ 1.0** (preferred) or official @ 0.5-0.7 (fallback) | Official LoRA fights I2V conditioning at high strength. TenStrip cond-safe zeroes out those layers. |
| 6 | Prompts | 150-200 words | 2-3 actions, 50-80 words | LTX can only execute 2-3 simultaneous actions |
**⚠️ Fix #5 was CORRECTED by follow-up deep research (2026-07-22, 15 sources).** The original claim (Distilled LoRA 0.7→1.0) was wrong. Community consensus: official Distilled LoRA at 1.0 causes quality degradation for I2V. The correct range is 0.5-0.7. TenStrip cond-safe is the solution — purpose-built for I2V at 1.0.
### Deep Research Dispatch for Artifact Investigation
When artifacts persist after applying the ranked fixes above, dispatch a focused deep-research pass with the exact setup and prompts. The pattern:
1. **Write the full research question to a file** — include: exact model chain, all render settings, all scene prompts verbatim, what's been tried (v4, v5), and specific research questions (e.g., "does ID LoRA cause artifacts on full-body action scenes?", "is fp8_scaled the worst variant?")
2. **Dispatch to research profile:** `hermes -p research -s deep-web-research chat -q "Read the full research question from <path>..." -Q --max-turns 600 --yolo`
3. **Expected output:** `/home/n8n/workspace/research/results/<YYYY-MM-DD>-ltx-2.3-artifacts-deep.md`
4. **Do NOT poll** — the `deep-research` skill's post-dispatch rule applies. Wait for the `notify_on_complete` notification.
5. **If the result file is missing after completion:** check the process log for the session_id, then check the ledger at `/tmp/research-<date>-<slug>.md`. If the ledger has only the strategy section (Move 0), the research didn't progress — re-dispatch with a fresh session. See `research-dispatch-pitfalls` Pitfall 12 for the full diagnosis workflow. Real failure (2026-07-22): deep research on LTX artifacts completed but result file never created — agent exited after Move 0.
See `references/artifact-deep-research-template.md` for the question template used in the 2026-07-22 dispatch (10 specific research questions, full setup, all 6 scene prompts).
### Fix Application Order (test after each)
1. Drop ID LoRA — zero-cost, biggest single impact
2. Switch to single-stage 16-20 steps — eliminates refiner smear risk
3. Download TenStrip cond-safe LoRA — purpose-built for I2V at 1.0
4. Set guide_strength to 1.0 — proper I2V anchoring (safe with ID LoRA dropped)
5. Switch to 768×512 — widescreen training distribution
6. Simplify prompts to 50-80 words — 2-3 actions max
7. Git pull deps (with caution — see Pitfalls: may land incompatible native workflows)
### Negative Prompt (updated)
```
no extra limbs, no face warp, no object duplication
no text artifacts, no floating logos, no watermark
no extreme motion blur, no rolling shutter wobble
no flicker, no frame-to-frame texture shift
no Dutch angle, no rapid handheld, keep horizon level
text, watermark, subtitle, logo, readable letters, garbled text
```
Added the text/watermark line — LTX-2.3's upscaler v1.0 was trained on data contaminated with endscreen logos (GitHub #148, HF discussion #13).
### Common Prompt Mistakes
| Mistake | Symptom | Fix |
|---------|---------|-----|
| guide_strength 1.0 | Subject splits into two, ghosting | Drop to 0.7 (0.5 for high motion) |
| zhuanchang on every scene | Wrong scene entirely, hallucinated content | Only use on actual transition/morph scenes |
| No camera direction | Static or random movement | Add dolly/pan/tracking/static |
| No shot framing | Inconsistent framing, zoom jumps | Add close-up/medium/wide/angle |
| Prompts too short (15-25 words) | Model fills gaps with random training data | 50-80 words minimum |
| No motion detail | Character freezes or glides unnaturally | Describe sequential action in present tense |
| No per-scene lighting | Lighting doesn't match scene context | Describe light source, quality, color temp |
| Same global prompt for all scenes | No scene-specific atmosphere | Vary lighting/audio/environment per scene |
| No temporal structure | Model doesn't know what to animate when | "Over 10 seconds: first X, then Y, finally Z" |
| Emotional labels without physical cues | Abstract expressions, no visible emotion | "Shoulders slumped, eyes downcast" not "sad" |
| Conflicting descriptions | Model averages competing signals | One speed, one camera, one lighting logic |
| Text/logos in prompts | Garbled text output | LTX cannot generate readable text |
### Prompting Workflow
1. Write the full prompt with all required elements (shot, camera, action, lighting, environment)
2. Only append `zhuanchang` if the scene involves a transformation/morph
3. Use the same character description across all scenes (from global prompt or character sheet)
4. Vary lighting and atmosphere per scene to match the setting
5. Test one scene first before rendering all 6
6. **MANDATORY: Validate every prompt against the 10-point checklist in `references/prompt-validation-checklist.md` BEFORE submitting to render queue.** This is a FIRM quality gate — do not skip. The user's standing rule: "ensure prompts match ltx standard. ALWAYS. This should be FIRM in memory and validate before EVERY run." If any check fails, fix the prompt and re-validate. Do not submit a workflow with a failing prompt.
7. Verify guide_strength is 1.0 in every scene JSON before submitting
## Story Structure (CRITICAL — session 2026-07-21)
The user's feedback on v4: "the videos had all kinds of inconsistencies" despite fixed wiring and good individual prompts. The root cause: the story didn't flow between scenes. Each scene was a standalone vignette (wake up → kitchen → porch → forest → stream → overlook) with no causal chain. LTX needs a narrative thread where each scene follows from the previous one.
### Story Design Rules
1. **Chain of events, not vignettes.** Each scene must be caused by the previous scene. "She discovers something → she runs → she hides → she chooses." Not "he wakes up → he makes coffee → he walks outside."
2. **One character, one journey.** Multi-character stories cause identity drift. The ID LoRA helps but isn't perfect across different faces.
3. **No dialogue, no plot twists.** LTX can't do dialogue well. Visual storytelling: action, reaction, environment, choice.
4. **6 scenes × 10s = 60s.** This is the sweet spot. Each scene is one beat in the story.
5. **Clear visual variety per scene.** Each scene should have a distinct setting, lighting, and camera language. This prevents the model from blending scenes together.
6. **Match LTX prompt style for EVERY scene.** See Prompting Rules above. Every scene prompt must have: shot type, camera movement, subject action (present tense, sequential), lighting, audio. No exceptions.
### Story Template
```
Scene 1: INCITING INCIDENT — character discovers/encounters something
Scene 2: ESCALATION — the situation intensifies, stakes rise
Scene 3: REACTION — character responds, makes a decision
Scene 4: CHASE/STRUGGLE — physical action, pursuit, or confrontation
Scene 5: LOW POINT — character is isolated, vulnerable, reflects
Scene 6: CHOICE/RESOLUTION — character makes the final decision, walks toward outcome
```
### User Preference: Detail Over Simplicity
The user initially asked for simpler stories, then reversed: "go back to your original." The detailed 4-story cyberpunk templates (Ghost in the Wire, Chrome Angels, The Last Human Job, Neon Baptism) are the preferred level of detail. Each story has: logline, chain of events, per-scene setting/action/camera, and start frame requirements. See `references/story-structure-guide.md` for the full 4-story templates.
## Multi-Story Workflow (CRITICAL — session 2026-07-21)
**Run one story at a time, end to end.** Do NOT batch all 4 stories. Complete each story fully before starting the next:
1. Generate start frames → wait for queue drain
2. Build scene JSONs → submit render → wait for queue drain
3. Verify frame counts (241 per scene, not 249)
4. Concat → upload to TrueNAS
5. Save all artifacts (prompts, JSONs, stock) to TrueNAS
6. Update state file
7. Only then start the next story
**Before scaling to a full 6-scene story, test with 2 clips first.** A 2-clip test (shared background, camera pan between subjects) validates the model chain, prompt quality, and transition smoothness at minimal cost before committing to a full render. See `references/claude-live-ssh-inspection.md` for the pattern of having Claude SSH into .202 to inspect live state and build the test plan.
### 2-Clip Test Pattern (Panorama + Frame-B Transition)
Proven pattern for testing continuous camera motion across clips (2026-07-22, two iterations):
1. **Generate one wide Flux panorama** (1536×512) with both subjects in a shared scene — guarantees identical background/lighting
2. **Crop 3 windows** (768×512 each): A (subject 1), B (center transition — EMPTY mid-room), C (subject 2)
3. **Clip 1:** Plain I2V from frame A, prompt drives a slow steady pan. Drop ID LoRA.
4. **Clip 2:** Plain I2V from **frame B** (the pre-rendered empty mid-room crop). Prompt continues the pan, reveals subject 2.
**CRITICAL: Do NOT use true-extend (extract last frame from Clip 1 → use as Clip 2 start).** True-extend carries latent memory of subject 1 into Clip 2. LTX hallucinates a second figure at subject 1's location even though the start frame shows empty room. Confirmed 2026-07-22: Clip 2 generated a second woman stepping up from the couch where the man was. Fix: use the pre-rendered empty frame B as Clip 2's start frame — clean start, no latent memory. Small seam risk at boundary but eliminates hallucination.
**Why frame-B transition, not FLF:** FLF (First-Last-Frame) decelerates toward its target keyframe — clip 1 slows down approaching B, clip 2 speeds up leaving it. This creates a velocity "hitch" at the seam. Frame-B transition uses plain I2V for both clips with the pre-rendered empty frame as Clip 2's anchor — constant velocity, no deceleration, no latent memory.
Full plan at `~/workspace/general/plans/2026-07-22-2clip-test-plan.md`. See `references/2clip-test-pattern.md`.
### Claude Live-SSH Inspection Pattern
When you need a plan built from live system state (not from memory or docs), have Claude SSH into .202 and inspect before planning:
1. **Write the question** to a local temp file, scp to 10.0.0.28
2. **Include SSH credentials in the prompt** — Claude needs `sshpass -p 'passw0rd' ssh [email protected]` to reach .202
3. **Tell Claude what to inspect** — model files, workflow JSONs, queue status, disk space, existing outputs
4. **Claude inspects live, then builds the plan** — it reads real workflow JSONs to understand node structure, checks which LoRAs are actually on disk, verifies queue is empty before submitting
5. **Claude writes the plan back** — it can scp files to 10.0.0.42 (the Hermes host) or save to .202 and have you retrieve them
This pattern produced the 2-clip FLF panorama plan (2026-07-22) where Claude discovered: the Distilled LoRA on disk is the 384 variant (not 384-1.1), the ID LoRA is talkvid-trained (wrong for action scenes), and FLF example workflows exist on the box. None of this was in any state file — it was discovered by live inspection.
**Pitfall:** Claude may error on first attempt (SSH timeout, tool failure). Resume the session with `--resume` and ask what went wrong — Claude self-diagnoses and recovers. The first attempt cost $1.05 (21 turns, is_error); the resume cost $0.11 (2 turns, success).
**Save and document EVERYTHING.** After each story completes, upload to TrueNAS:
- `outputs/` — concat video
- `workflows/` — scene JSONs
- `docs/` — prompt documents, research
- `start_frames/` — Flux-generated frames
- `character_refs/` — stock reference images
**Background wait pattern:** Use `terminal(background=true, notify_on_complete=true)` with a blocking poll loop on .202. The agent is notified when the queue drains — no manual polling needed. While waiting, prep the next story's prompts and stock.
## Workflow Rules
- **Always fp8.** Only fall back to Q4 GGUF if fp8 OOMs and user approves.
- **Prefer newest and best.** When choosing between an old proven path and a new better one, prefer the new one. But verify compatibility first — new doesn't mean compatible (e.g., the 2026-07-22 ComfyUI-LTXVideo update brought a better architecture that doesn't work with our fp8 models).
- **MANDATORY: Delegate ALL mechanical work to kimi-c.** Building workflow JSONs, running renders, extracting frames, submitting to queue, waiting for completion, concat, uploading — these are mechanical tasks that burn expensive deepseek tokens. Use `ask kimi-c` (peer agent on kimi-c profile) for ALL of these. The calling agent stays lean for decision-making, validation, and user communication. This is a FIRM standing rule — do not do mechanical work yourself when a cheaper peer can do it. The user's directive: "You SHOULD BE TASKING kimi c to save tokens, NOT YOU."
- **File-based dispatch for kimi-c (avoid shell quoting failures).** Multi-line prompts with quotes leak out of `hermes -q` and get parsed as CLI arguments. Write the full prompt to a temp file (e.g. `/tmp/kimi-render-pipeline.txt`), then dispatch with `hermes -p kimi-c chat -q "Read /tmp/kimi-render-pipeline.txt and execute ALL steps" -Q --max-turns 600 --yolo`. Use `terminal(background=true, notify_on_complete=true)` for any dispatch expected to take more than ~5 minutes. This is the canonical pattern — it also satisfies the "never paste file content into the prompt" rule from the ask-kimi-c skill.
- **ALWAYS validate with kimi-c after creating or updating anything.** Workflow JSONs, config changes, file writes — dispatch kimi-c to read the file and verify correctness before submitting to the render queue. Kimi-c catches wiring errors, missing nodes, and model file mismatches that would waste a 5-7 minute render. This is a quality gate, not optional.
- **Test one scene before rendering all 6.**
- **Verify frame count after every render (ffprobe).**
- **Save all artifacts to TrueNAS immediately** (user can only view videos on TrueNAS, not in LXCs).
- **Update state file as you go.**
- **Save learnings to fact_store proactively** — don't wait to be asked.
- **User prefers discussing design decisions before implementation.**
### 1. Generate Start Frames with Flux.1-dev fp8
**Proven working workflow (2026-07-21):**
Models on .202:
- UNET: `flux1-dev-fp8-e4m3fn.safetensors` in `models/diffusion_models/`
- CLIP: `t5xxl_fp8_e4m3fn.safetensors` + `clip_l.safetensors` in `models/text_encoders/`
- VAE: `ae.safetensors` in `models/vae/`
Working node graph (512×512 txt2img):
```json
{
"5": {"class_type": "CLIPTextEncode", "inputs": {"text": "<PROMPT>", "clip": ["11", 0]}},
"6": {"class_type": "CLIPTextEncode", "inputs": {"text": "blurry, low quality, distorted face, bad anatomy, watermark, text, logo", "clip": ["11", 0]}},
"7": {"class_type": "FluxGuidance", "inputs": {"conditioning": ["5", 0], "guidance": 3.5}},
"8": {"class_type": "VAEDecode", "inputs": {"samples": ["3", 0], "vae": ["10", 0]}},
"9": {"class_type": "SaveImage", "inputs": {"filename_prefix": "ltx_start_frame_XX", "images": ["8", 0]}},
"10": {"class_type": "VAELoader", "inputs": {"vae_name": "ae.safetensors"}},
"11": {"class_type": "DualCLIPLoader", "inputs": {"clip_name1": "t5xxl_fp8_e4m3fn.safetensors", "clip_name2": "clip_l.safetensors", "type": "flux"}},
"16": {"class_type": "UNETLoader", "inputs": {"unet_name": "flux1-dev-fp8-e4m3fn.safetensors", "weight_dtype": "fp8_e4m3fn"}},
"3": {"class_type": "KSampler", "inputs": {"seed": 42, "steps": 20, "cfg": 1.0, "sampler_name": "euler", "scheduler": "simple", "denoise": 1.0, "model": ["16", 0], "positive": ["7", 0], "negative": ["6", 0], "latent_image": ["27", 0]}},
"27": {"class_type": "EmptySD3LatentImage", "inputs": {"width": 512, "height": 512, "batch_size": 1}}
}
```
**Submission:** MUST wrap in `{"prompt": <workflow>}` envelope. The ComfyUI API rejects bare workflow JSON with `"no_prompt"` error.
```bash
# Build JSON, then submit:
curl -s -X POST http://localhost:8188/prompt -H "Content-Type: application/json" -d @/tmp/flux_scene_01.json
```
**Output:** Files land in `~/comfy-ui/output/` as `<filename_prefix>_00001_.png`. Move to `~/comfy-ui/input/` for LTX Director to find them.
- Use Flux.1-dev fp8 or Qwen-Image-2512 on .202
- 512×512, photorealistic
- Save to `~/comfy-ui/input/`
### 2. Generate TTS Audio
- Edge TTS (free) or Piper
- ~2-4s per scene
- Save to `/tmp/ltx_audio/`
### 3. Build Scene JSONs
- Template: use an existing scene JSON from a prior render
- Modify: start_frame path, audio path, segment prompt
- For Transition LoRA: add `LoraLoaderModelOnly` node, rewire chain, append `zhuanchang` to prompts
- Save to `/tmp/api_scene_XX.json`
### 4. Submit to Queue
```bash
curl -s -X POST http://localhost:8188/prompt -H "Content-Type: application/json" -d @/tmp/api_scene_XX.json
```
- Submit all scenes at once
- Queue processes sequentially (one GPU)
### 5. Wait for Completion
- Poll queue: `curl -s http://localhost:8188/queue | python3 -c "import json,sys; d=json.load(sys.stdin); print(len(d['queue_running']), len(d['queue_pending']))"`
- GPU: `nvidia-smi --query-gpu=utilization.gpu,memory.used --format=csv,noheader`
- ~5-7 min per scene at 8 steps
- Blocking wait loop (from Hermes host):
```bash
sshpass -p 'passw0rd' ssh [email protected] "while true; do q=\$(curl -s http://localhost:8188/queue | python3 -c \"import json,sys; d=json.load(sys.stdin); print(len(d['queue_running'])+len(d['queue_pending']))\"); if [ \"\$q\" -eq 0 ]; then echo 'QUEUE_EMPTY'; break; fi; echo \"queue: \$q\"; sleep 30; done"
```
### 6. Identify Output Files
```bash
python3 << 'PYEOF'
import subprocess, os, re
outdir = os.path.expanduser("~/comfy-ui/output/video")
for f in sorted(os.listdir(outdir)):
if not f.startswith("LTX_Director_"): continue
path = os.path.join(outdir, f)
r = subprocess.run(["ffprobe", "-v", "quiet", "-show_entries", "format_tags=prompt", "-of", "csv=p=0", path], capture_output=True, text=True)
img = re.search(r"imageFile.*?ltx_start_frame_(\d+)", r.stdout)
scene = f"Scene_{img.group(1)}" if img else "?"
has_trans = "LoraLoaderModelOnly" in r.stdout
print(f"{f} | {scene} | Transition={has_trans}")
PYEOF
```
### 7. Concat with ffmpeg
```bash
# Create concat list
cat > /tmp/concat.txt << EOF
file '/home/n8n/comfy-ui/output/video/LTX_Director_XXXXX_.mp4'
file '/home/n8n/comfy-ui/output/video/LTX_Director_YYYYY_.mp4'
...
EOF
# Stream copy (no re-encode)
ffmpeg -f concat -safe 0 -i /tmp/concat.txt -c copy ~/comfy-ui/output/video/LTX_Director_60s.mp4 -y
```
### 8. Save to Stock
- **smbclient is NOT on .202** — scp files to Hermes host first, then upload to TrueNAS from there
- Upload outputs: `smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material\\outputs; put <local_path> <filename>'`
- Upload workflow JSONs: `smbclient -N //10.0.0.117/proxmoxBackup -c 'cd ai_vid_stock_material\\workflows; put <local_path> <filename>'`
- Update README.md inventory
- See `ai-vid-stock` skill for full commands
## Stock Materials
All stock materials (start frames, audio, character refs, workflows, outputs) are stored on TrueNAS at `//10.0.0.117/proxmoxBackup/ai_vid_stock_material/`. Use the `ai-vid-stock` skill for add/search/remove operations.
**Known gap (2026-07-21):** `better-search` finds sources but doesn't download them to stock. The research agent reports URLs; the dispatcher agent must manually download and upload. Future: extend `better-search-research` methodology to accept a `--target` parameter and auto-download top results to the specified stock directory.
**Character reference sources (from better-search research):**
- freeaivideohub.com/character-sheets — 12 free photorealistic multi-view character sheets
- Pexels API — 700K+ free portrait photos, commercial use
- FFHQ — 70K faces at 1024×1024 (NVIDIA, non-commercial)
- CivitAI — community LoRAs and LTX workflows
## Pitfalls
- **CRITICAL: True-extend (extract last frame → use as next clip start) carries latent memory.** LTX remembers subjects from prior clips even when the start frame shows empty space. Confirmed 2026-07-22: Clip 2 hallucinated a second woman stepping up from the couch where the man was in Clip 1. Fix: use the pre-rendered empty mid-room frame B as Clip 2's start frame instead of the extracted last frame. Clean start, no latent memory. See §2-Clip Test Pattern.
- **ffmpeg last-frame extraction:** `ffmpeg -sseof -3 -i input.mp4 -vsync vfr -q:v 2 output.png` may fail. Working alternative: `ffmpeg -sseof -3 -i input.mp4 -update 1 -frames:v 1 -q:v 2 output.png`. The `-update 1` flag is needed for single-frame PNG output from video input.
- **CRITICAL: git pull on ComfyUI-LTXVideo may land incompatible native workflows.** The 2026-07-22 update (30K lines) brought a new native single-stage architecture (CheckpointLoaderSimple, LTXVScheduler, SamplerCustomAdvanced, GemmaAPITextEncode) that uses full checkpoints (46 GB), not our fp8 UNET-only transformer (23 GB). The new workflow drops LTXDirector entirely. Our fp8 chain (UNETLoader → LTX2LoraLoaderAdvanced → LTXDirector) is incompatible with the new architecture. **Before git pulling, snapshot the working state.** If the pull lands new example workflows, do NOT assume they work with our fp8 models — verify compatibility first. The new architecture requires a full checkpoint that won't fit 24 GB VRAM.
- **CRITICAL: Upload to TrueNAS after EVERY render.** The user can only view videos on TrueNAS (10.0.0.117), not in LXC containers. scp from .202 to Hermes host, then smbclient to TrueNAS. Do NOT skip this — the user has no other way to review output. (Learned 2026-07-22: user said "I can only view videos on truenas, not in lxc's.")
- **CRITICAL: Do NOT interrupt a running Claude session.** If Claude is mid-build (background process running), do not scp new question files or send follow-ups unless the user explicitly says "tell Claude now." Wait for the session to complete. Mid-build interruptions can cause the session to error out. (Learned 2026-07-22: sent a fact_store instruction mid-build; user corrected: "I said when claude is complete.")
- **CRITICAL: Claude's intermediate errors are normal self-correction.** Claude will make mistakes, hit errors, then try a different approach. `is_error: true` on intermediate turns does NOT mean the session failed. Wait for the final turn output. Only diagnose after the background process completes. Jumping to conclusions mid-session wastes turns and money. (Learned 2026-07-22: killed a working session twice, $1.78 wasted. User: "you just need to wait for the final turn output. Not jump to conclusions.")
- **Transition LoRA uses LoraLoaderModelOnly, not LTX2LoraLoaderAdvanced.** Wiring it wrong silently fails — the workflow runs but produces no transition effect.
- **`zhuanchang` trigger word is required** for Transition LoRA to activate. Append to end of segment prompts.
- **CFG must be 1.0** for distilled model. Higher values cause artifacts.
- **Queue is sequential** — submitting 6 scenes means ~30-40 min total. Use the blocking wait loop from step 5.
- **Output files accumulate** — the Director workflow produces 2 outputs per scene (guide pass + main pass). Identify the final output by checking for `LoraLoaderModelOnly` in metadata (Transition batch) or by resolution (512×512 = fp8 batch).
- **cifs kernel module not available** on Hermes host — use smbclient for TrueNAS, not mount.cifs.
- **smbclient is NOT installed on .202** — scp files to Hermes host first, then upload to TrueNAS from there. Do not try to install smbclient on .202 (no root access).
- **State file is the crash-recovery artifact** — update `~/workspace/general/ltx-pipeline-state.md` as you go. A new session reads it to resume.
- **ComfyUI API requires `{"prompt": <workflow>}` envelope.** Submitting bare workflow JSON returns `"no_prompt"` error. Always wrap in the prompt key.
- **241 frames is normal for 10s@24fps.** The Director may produce 241 due to a 1-frame rounding quirk. 249 frames means the wiring bug is present (guide frames leaked). Verify with ffprobe.
- **Duration control: set `segment[\"length\"]`, NOT `duration_seconds` or `segment[\"end\"]`.** The LTXDirector ignores node-level `duration_seconds` and segment `end` — it uses `segment[\"length\"]` as the frame count. For 5s@24fps: `td[\"segments\"][0][\"length\"] = 120`. Setting only `duration_seconds` or `end` silently produces the full 10s output. Confirmed 2026-07-21: two failed attempts before finding the correct field.
- **Story must have a causal chain.** Standalone vignettes (wake up → kitchen → porch → forest) produce visual inconsistencies because the model has no narrative thread. Each scene must follow from the previous one. See `references/story-structure-guide.md` for the full 4-story templates and design rules.
- **User prefers detailed stories over simplified ones.** When the user said "keep it simple" and then "go back to your original," the original detailed templates were preferred. Don't over-simplify — the 4-story cyberpunk templates with loglines, scene tables, and character descriptions are the right level of detail.
+215
View File
@@ -0,0 +1,215 @@
---
name: stock-search-research
description: Stock material search methodology — 3-move flow (search → evaluate → download+classify+upload to TrueNAS), 3-loop cap, /tmp ledger. Opt-in skill for the research profile.
version: 1.0.0
author: Hermes Agent
metadata:
hermes:
tags: [research, search, stock, download, truenas, methodology]
related_skills: [better-search-research, deep-web-research]
---
# stock-search-research — Stock Material Search + Download Methodology
Loaded explicitly via `-s stock-search-research`. Not loaded during normal
interactive use of the research profile. This skill enforces a 3-move research
flow with a hard 3-loop cap, ending in file download and TrueNAS upload.
## §1 Overview
This skill performs a 3-move research flow:
1. **Move 1: Initial Search** — 2-3 SearXNG searches for downloadable stock
materials matching the query, read top results, write structured summary to
`/tmp/stock-<sid>.md`.
2. **Move 2: AI Evaluation + Refine** — Read the ledger from disk, self-evaluate
for quality/relevance/license, optionally run 1-2 refinement searches.
3. **Move 3: Download + Classify + Upload** — Read full ledger, download top
files to `/tmp/`, classify by type, upload to TrueNAS via smbclient, update
inventory.
**Hard loop cap: 3** (1 initial search + up to 2 refinements). The cap is
enforced by the ledger — at most 1 `## Search` block and 2 `## Refinement`
blocks. No saturation-based continuation. No `--resume` — every dispatch is a
fresh session with a new ledger and a new 3-loop budget.
**Total budget: 50 turns.** The 3-loop cap is the real limit; 50 turns is a
safety net. If the agent hits 50, deliver partial results with a note.
**Ledger:** `/tmp/stock-<sid>.md` — a flat structured file. The ledger forces a
re-read from disk at each move so details that scrolled out of context are not
lost.
**TrueNAS target:** `//10.0.0.117/proxmoxBackup/ai_vid_stock_material/`
Access via `smbclient -N //10.0.0.117/proxmoxBackup`.
## §2 Parsing the Target Category
The question string contains `--target <category>` at the end. Parse it:
- `start_frames``ai_vid_stock_material/start_frames/`
- `character_refs``ai_vid_stock_material/character_refs/`
- `audio``ai_vid_stock_material/audio/`
- `misc_images``ai_vid_stock_material/misc_images/`
- `all` or missing → classify by file extension (see §4)
Strip `--target <category>` from the question before using it as the search query.
## §3 Move 1: Initial Search
**Turns 1-5.** Gather downloadable stock materials.
1. Run 2-3 SearXNG searches with different framings:
- One broad: `<query> free download stock image`
- One specific: `<query> site:pexels.com OR site:unsplash.com OR site:pixabay.com`
- One targeted: `<query> site:huggingface.co OR site:civitai.com` (for AI-specific stock)
- For audio: add `site:freesound.org OR site:epidemicsound.com`
- Use `filetype:png OR filetype:jpg` when searching for images
2. Read top 1-3 results per search with `mcp_searxng_web_url_read`.
3. For each result, identify:
- Direct download URL (not a page — the actual file URL)
- File type (image, audio, video)
- License (free/commercial/attribution required)
- Resolution/quality notes
4. Write a structured summary to `/tmp/stock-<sid>.md`:
```
## Question
<verbatim question with --target stripped>
## Target Category
<category>
## Search 1: <query>
- Source: <url>
- Download URL: <direct file URL>
- Type: image/png | image/jpg | audio/mp3 | audio/wav
- License: free | commercial | attribution | unknown
- Notes: <resolution, quality, relevance>
## Search 2: <query>
...
```
**SearXNG error handling:** Same as better-search-research §2 — VPN reconnect
on first failure, different framing on second, proceed to Move 3 on third.
## §4 Move 2: AI Evaluation + Refine
**Turns 6-15.** Evaluate quality and fill gaps.
1. Read `/tmp/stock-<sid>.md` from disk.
2. Self-evaluate using these criteria (write the eval to the ledger):
- **Relevance:** Does each result match the query intent?
- **Quality:** Resolution sufficient? (Images: min 512px. Audio: min 44.1kHz.)
- **License:** Safe to use? Prefer free/commercial. Flag attribution-required.
- **Downloadability:** Is there a direct download URL? Skip pages that only
show previews.
- **Coverage:** Enough results? (Aim for 3-10 good files.)
3. IF gaps → write `## Refinement <N>: <new query>` to ledger, run 1-2 more
searches, append findings.
4. Hard cap: 2 refinements total. Track count in the ledger.
5. IF no gaps (or cap hit) → proceed to Move 3.
**Ledger format for refinements:**
```
## Refinement 1: <new query>
- Source: <url>
- Download URL: <direct file URL>
- Type: <file type>
- License: <license>
- Notes: <notes>
```
## §5 Move 3: Download + Classify + Upload
**Turns 16-50.** Download files and upload to TrueNAS.
1. Read full ledger from `/tmp/stock-<sid>.md`.
2. Create a temp directory: `mkdir -p /tmp/stock-dl-<sid>/`
3. For each result with a direct download URL:
- Download: `wget -q -P /tmp/stock-dl-<sid>/ "<download_url>"`
- Skip if download fails (3 retries max, then blacklist)
- Skip if file is < 1KB (likely an error page)
4. Classify each downloaded file:
- `.png`, `.jpg`, `.jpeg`, `.webp``start_frames/` (if target is `all` or `start_frames`)
- `.mp3`, `.wav`, `.ogg`, `.flac``audio/`
- `.mp4`, `.webm`, `.mov``misc_images/` (no video category yet)
- Everything else → `misc_images/`
- If a specific `--target` was given, ALL files go to that category
5. Upload each file to TrueNAS:
```bash
smbclient -N //10.0.0.117/proxmoxBackup -c "cd ai_vid_stock_material\\<category>; put /tmp/stock-dl-<sid>/<filename> <filename>"
```
- Use backslashes in SMB paths: `ai_vid_stock_material\\start_frames`
- If a file with the same name exists, append `-<N>` before the extension
6. Update the inventory README on TrueNAS:
```bash
# Download current README
smbclient -N //10.0.0.117/proxmoxBackup -c "cd ai_vid_stock_material; get README.md /tmp/stock-dl-<sid>/README.md"
# Append new entries
echo "## Stock Search: <date> — <query>" >> /tmp/stock-dl-<sid>/README.md
for each uploaded file:
echo "- <category>/<filename> — <source_url> — <license>" >> /tmp/stock-dl-<sid>/README.md
# Upload updated README
smbclient -N //10.0.0.117/proxmoxBackup -c "cd ai_vid_stock_material; put /tmp/stock-dl-<sid>/README.md README.md"
```
7. Clean up: `rm -rf /tmp/stock-dl-<sid>/`
8. Report to stdout:
```
Downloaded N files to TrueNAS:
- ai_vid_stock_material/<category>/<filename> (source: <url>, license: <license>)
- ...
```
**Download safety:**
- Max 20 files per dispatch (prevents runaway downloads)
- Max 500MB total per dispatch
- Skip any URL that redirects to a different domain (potential malware)
- Skip `.exe`, `.dmg`, `.pkg`, `.msi` files (executables)
- If smbclient fails, report the error — do not retry more than 3 times
## §6 Safety Boundaries
These persist across all turns — they are in the skill, not in fading context:
- **Confined to /tmp.** All downloads go to `/tmp/stock-dl-<sid>/`. Never write
outside /tmp except for TrueNAS uploads.
- **No self-provisioning.** Never install software. No pip, npm, apt, docker, or
any package manager. Use only what's already configured (wget, smbclient, ffprobe).
- **No repeat searches.** If you catch yourself searching the same thing twice,
stop. That sub-question is saturated.
- **Blacklist after 3 failures.** If a URL returns an error 3 times, blacklist it
and move on. Do not retry indefinitely.
- **Local and free only.** No internet-based paid services, no SaaS APIs with
billing, no metered endpoints.
- **Max 20 files, 500MB total per dispatch.** Hard cap to prevent runaway downloads.
- **No executables.** Skip `.exe`, `.dmg`, `.pkg`, `.msi`.
## §7 Cap-Hit Behavior
When the 3-loop cap is hit (1 initial search + 2 refinements used) without
satisfaction:
1. Proceed directly to Move 3 — download what you have.
2. In the stdout report, add a note:
> **Note:** Loop cap reached (3 loops / 1 initial + 2 refinements). Some
> results may not be fully explored. For exhaustive coverage, re-dispatch with
> a refined question or use `deep-research`.
When the 50-turn ceiling is hit:
1. Download whatever files have been identified so far.
2. Report with a header note: "incomplete — turn ceiling hit at Move N."
## §8 See Also
- `better-search-research` — medium-depth research without download (report-only)
- `deep-web-research` — exhaustive multi-source research with disconfirmation
- `stock-search` (dispatcher) — the operator-facing skill that triggers this
methodology. Installed on all profiles; delegates to the research profile via
`research -s stock-search-research`.
- `ai-vid-stock` — manual stock management on TrueNAS (list, add, remove)
+114
View File
@@ -0,0 +1,114 @@
---
name: stock-search
description: 'Search the web for downloadable stock materials and auto-upload to TrueNAS. Delegates to the research profile for a 3-move flow: search → evaluate → download+classify+upload. Trigger phrases: "stock search for X", "find stock for X", "download stock for X".'
version: 1.0.0
author: Hermes Agent
metadata:
hermes:
tags: [research, search, stock, download, truenas, ai-video]
related_skills: [better-search, ai-vid-stock, deep-research]
---
# stock-search — Stock Material Search + Download Dispatcher
## §1 Overview
`stock-search` is a dispatcher skill that searches the web for downloadable stock
materials (images, audio, video clips) and auto-uploads them to TrueNAS in the
correct directory. It delegates to the research profile for a 3-move flow:
search → evaluate → download+classify+upload.
**Architecture:** Two-skill contract. This dispatcher is installed on all
profiles and owns trigger detection, optional clarifying questions (max 3), the
dispatch command, and session-id capture. The methodology `stock-search-research`
runs ONLY on the research profile and owns the actual 3-move flow with
download+upload. The dispatcher always delegates to the research profile via
`research -s stock-search-research` — the dispatcher never runs the search itself.
**Trigger phrases:** `stock search for X`, `find stock for X`, `download stock for X`.
These are the ONLY phrases that fire this skill.
## §2 When to Use / When NOT to Use
**TRIGGER RULE (absolute):** If the user says "stock search for X" or "find stock
for X" or "download stock for X", you MUST dispatch. No exceptions.
| Question shape | Tool |
|---|---|
| "Stock search for cyberpunk backgrounds" | `stock-search` (this skill) |
| "Better search for LTX settings" | `better-search` |
| "Deep research on LTX pipeline" | `deep-research` |
| "Upload this file to stock" | `ai-vid-stock` directly |
## §3 Command — RUN THIS EXACTLY
```bash
research -s stock-search-research chat -q "<question> --target <category>" -Q --max-turns 50 --yolo
```
**`research` is a profile alias** (`hermes profile alias research`). Equivalent to
`hermes -p research`.
**Flag rationale:**
- `research` — profile alias, selects the research profile
- `-s stock-search-research` — hardcoded methodology skill
- `-Q` — quiet mode
- `--max-turns 50` — safety net (3-loop cap is the real limit)
- `--yolo` — required for headless one-shot dispatch
**Target categories** (passed in the question string as `--target <category>`):
- `start_frames` — first/last frame images for I2V
- `character_refs` — character reference images
- `audio` — TTS clips, ambient sounds, music
- `misc_images` — unsorted images, inspiration
- `all` — let the methodology classify by file type
If no `--target` is specified, the methodology defaults to `misc_images`.
## §4 Clarifying Questions (Max 3)
Only ask if the target category is ambiguous. Default: 0 questions. Hard cap: 3.
If the user says "stock search for cyberpunk" without specifying a category, ask:
"Which category — start_frames, character_refs, audio, or misc_images?"
## §5 Delivery
After dispatching:
1. **Capture `session_id`** from the research agent's output.
2. **Report** the session_id and expected TrueNAS paths:
```
session_id: <sid> (reference only — do not --resume)
Files will land in: ai_vid_stock_material/<category>/ on TrueNAS
```
3. **Return control to the operator.** Do NOT poll, do NOT check for results.
The operator checks TrueNAS when they want to.
The methodology uploads files directly to `//10.0.0.117/proxmoxBackup/ai_vid_stock_material/<category>/`
via smbclient. No intermediate report file — the files on TrueNAS are the deliverable.
## §6 No-Resume Rule
**No `--resume`.** Every follow-up is a fresh dispatch with a new session_id and
new 3-loop budget.
## §7 Common Pitfalls
1. **`--yolo` is required.** Headless one-shot. Without it, approval prompts fail closed.
2. **`--max-turns 50` is the safety net, not the budget.** 3 loops is the cap.
3. **Don't poll, don't check, don't background.** Return control to the operator
immediately after capturing the session_id.
4. **Max 3 clarifying questions.** Multi-part questions get condensed or split.
5. **No `--resume`.** Every dispatch is independent.
6. **The 3 triggers are the only phrases that fire this skill.** Don't add
`look for stock` or other variants — they collide with normal agent tasks.
7. **The `-p` flag exists. Do NOT hallucinate that it doesn't.** `hermes -p research`
is standard. If unsure, run `hermes --help` to verify.
## §8 See Also
- `better-search` — medium-depth research without download (report-only)
- `deep-research` — exhaustive multi-source research with disconfirmation
- `ai-vid-stock` — manual stock management on TrueNAS (list, add, remove)
- `nordvpn` — VPN management (methodology auto-reconnects on search failure)