Unified development orchestration. Tasks, campaigns, memory.
Unified orchestration for FTL tasks, campaigns, and memory queries. Invoke this skill for any `/ftl` request—it spawns router/builder/learner for tasks, planner/synthesizer for campaigns, or runs inline memory queries.
/plugin marketplace add enzokro/crinzo-plugins/plugin install ftl@crinzo-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Unified entry point for task execution, campaign orchestration, and memory queries.
This skill is the ONLY valid entry point for FTL operations.
DO NOT:
campaign.py directly from Claude Codeftl:router, ftl:builder, or other agents directlyThe orchestrator (this skill) manages all agent spawning and state transitions. Violating this constraint causes workspace/campaign desync and gate failures.
If user asks to use FTL: Invoke THIS skill. Do not improvise the workflow.
| Input Pattern | Mode | Flow |
|---|---|---|
/ftl <task> | TASK | router → builder → learner |
/ftl campaign <obj> | CAMPAIGN | planner → tasks[] → synthesize |
/ftl query <topic> | MEMORY | inline CLI query |
/ftl status | STATUS | inline CLI queries |
You MUST perform these steps before EVERY ftl:router spawn. No exceptions.
.ftl/cache/session_context.md.ftl/cache/workspace_state.md[session_context.md contents]
[workspace_state.md contents]
---
Campaign: ...
Task: ...
Skipping injection → router runs redundant git branch, ls .ftl/workspace, cat package.json.
Each redundant call wastes tokens. Injection eliminates ~20 Bash calls per campaign.
session_context.md: Static (SessionStart)workspace_state.md: Dynamic (updated after EVERY agent)Router also self-checks cache as backup. Both mechanisms must work.
Delta caching handled via SubagentStop → .ftl/cache/delta_contents.md.
Agents read this themselves per their instructions.
Main thread spawns phases directly (subagents cannot spawn subagents):
1. Task(ftl:router) with task description
Returns: direct | full | clarify
If full: also returns workspace path (router creates it)
2a. If direct:
Task(ftl:builder) — implement immediately, no workspace
2b. If full:
[Workspace already created by router]
Task(ftl:builder) — implement within Delta
If builder fails verification:
Task(ftl:reflector) — diagnose, return RETRY or ESCALATE
Task(ftl:learner) — extract patterns, update index
2c. If clarify:
Return question to user
Direct (no workspace):
Full (with workspace):
Router merges assess + anchor: explores AND routes in one pass.
For compound objectives requiring multiple coordinated tasks.
source ~/.config/ftl/paths.sh 2>/dev/null && ACTIVE=$(python3 "$FTL_LIB/campaign.py" active 2>/dev/null)
If campaign exists, skip to Step 5 (task execution).
DO NOT skip this step. DO NOT manually create campaigns.
Task(ftl:planner) with prompt:
Objective: $OBJECTIVE_FROM_ARGUMENTS
Return markdown with ### Tasks section.
Planner returns: PROCEED | CONFIRM | CLARIFY
After CLARIFY: Re-invoke THIS flow from Step 2. Do NOT continue as Claude Code.
python3 "$FTL_LIB/campaign.py" campaign "$OBJECTIVE"
Command is campaign, NOT create
CRITICAL: Use add-tasks-from-plan, NOT add-task
echo "$PLANNER_OUTPUT" | python3 "$FTL_LIB/campaign.py" add-tasks-from-plan
Tasks are created with 3-digit sequence numbers (001, 002, etc.).
For each task in sequence, spawn exactly these agents:
1. Router — invoke with campaign context:
Task(ftl:router) with prompt:
Campaign: $OBJECTIVE
Task: $SEQ $SLUG
[description]
The Campaign: prefix forces router to create workspace.
2. Builder — implement within workspace:
Task(ftl:builder) with prompt:
Workspace: [path returned by router]
3. Update — mark task complete:
python3 "$FTL_LIB/campaign.py" update-task "$SEQ" complete
DO NOT spawn ftl:learner in campaigns. Synthesizer handles pattern extraction at campaign end.
update-task enforces workspace gate.
python3 "$FTL_LIB/campaign.py" complete
# Then Task(ftl:synthesizer)
Critical:
campaign.py campaign, NOT campaign.py createadd-tasks-from-plan, NOT add-task SEQ SLUG DESCCampaign: prefix to force workspace creationQuery the decision graph for precedent (inlined, no agent spawn):
source ~/.config/ftl/paths.sh 2>/dev/null && python3 "$FTL_LIB/context_graph.py" query "$TOPIC"
Main thread formats and displays ranked decisions.
┌────────────────────────────────────────────────────────────┐
│ CAMPAIGN │ TASK │ MEMORY │
├────────────────────────────────────────────────────────────┤
│ Query precedent ────→│ │←── query │
│ │ │ (inline) │
│ Delegate task ────→│ router→builder→ │ │
│ │ reflector (if fail) │ │
│ │ Creates workspace file │ │
│ │ │ │
│ Gate on workspace ←───│ Returns _complete.md │ │
│ │ │ │
│ Signal patterns ────→│ │←── signal │
│ │ │ │
│ Synthesizer (end)────→│ Learner (TASK only) │←── mine │
└────────────────────────────────────────────────────────────┘
6 Agents: router, builder, reflector, learner, planner, synthesizer
Task state persists in workspace files:
.ftl/workspace/NNN_task-slug_status[_from-NNN].md
Status: active | complete | blocked
All state management via Python CLIs:
source ~/.config/ftl/paths.sh
# Workspace
python3 "$FTL_LIB/workspace.py" stat
python3 "$FTL_LIB/workspace.py" lineage NNN
# Memory
python3 "$FTL_LIB/context_graph.py" query "$TOPIC"
python3 "$FTL_LIB/context_graph.py" mine
python3 "$FTL_LIB/context_graph.py" signal + "#pattern/name"
# Campaign
python3 "$FTL_LIB/campaign.py" active
python3 "$FTL_LIB/campaign.py" campaign "$OBJECTIVE"
python3 "$FTL_LIB/campaign.py" update-task "$SEQ" complete
| Constraint | Meaning |
|---|---|
| Present over future | Current request only |
| Concrete over abstract | Specific solution, not framework |
| Explicit over clever | Clarity over sophistication |
| Edit over create | Modify existing first |
No new abstractions. No files outside Delta.