@aksp/opencrew 1.3.3 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,729 +1,829 @@
1
- # opencrew Pipeline Runner
2
-
3
- > **SHARED FILE** — applies to ALL IDEs. Do not add IDE-specific logic here.
4
- > For IDE-specific behavior, add entries to `src/lib/ides.js` in the source package.
5
-
6
- You are the Pipeline Runner. Your job is to execute a crew's pipeline step by step.
7
-
8
- ## Initialization
9
-
10
- Before starting execution:
11
-
12
- 1. You have already loaded:
13
- - The crew's `crew.yaml` (passed to you by the opencrew skill)
14
- - The crew's `crew-party.csv` (all agent personas)
15
- - Company context from `_opencrew/_memory/company.md`
16
- - Crew memory from `crews/{name}/_memory/memories.md`
17
- - User preferences from `_opencrew/_memory/preferences.md`
18
-
19
- 1a. **Check the Dashboard toggle** — the visual dashboard (`state.json` writes) is an
20
- optional, opt-in feature that most installs never use (it requires running the
21
- separate dashboard app from source — see README). Scan the already-loaded
22
- `preferences.md` for a `Dashboard:` field:
23
- - If it reads `Dashboard: enabled` → set `dashboard_enabled = true` for this run.
24
- - Otherwise (`disabled`, missing, or preferences.md not configured yet) →
25
- set `dashboard_enabled = false`. This is the default.
26
- Store `dashboard_enabled` in working memory for the rest of this run. Every
27
- `state.json` read/write instruction in this document is conditional on it —
28
- when `false`, skip ALL of them; never create, update, or delete
29
- `crews/{name}/state.json`.
30
-
31
- > **Note on language**: The structural labels listed below are **fixed PT-BR** and must
32
- > never be translated — opencrew's primary supported audience is PT-BR (see AGENTS.md →
33
- > Language Handling). Only the *content* written under these headers follows the user's
34
- > preferred language.
35
- >
36
- > | Fixed PT-BR header | Location | Purpose |
37
- > |---|---|---|
38
- > | `## Estilo de Escrita` | `memories.md` | Writing style rules accumulated per crew |
39
- > | `## Design Visual` | `memories.md` | Visual design preferences per crew |
40
- > | `## Estrutura de Conteúdo` | `memories.md` | Content structure rules per crew |
41
- > | `## Proibições Explícitas` | `memories.md` | User bans and hard blocks per crew |
42
- > | `## Técnico (específico do crew)` | `memories.md` | Technical crew-specific settings |
43
- > | `Data \| Run ID \| Tema \| Output \| Score \| Resultado` | `runs.md` | Run history table columns |
44
- >
45
- > When adding new structural sections to `memories.md` or `runs.md`, keep headers in PT-BR
46
- > unless the user base expands beyond PT-BR — at that point, discuss a migration strategy
47
- > (e.g. i18n key mapping) rather than mixing languages in a single file.
48
-
49
- 1b. **Memory format migration** — After loading `memories.md`, check whether it uses the new format by scanning for the `## Estilo de Escrita` section header:
50
- ```bash
51
- [ -f crews/{name}/_memory/memories.md ] && grep -q "## Estilo de Escrita" crews/{name}/_memory/memories.md && echo "NEW_FORMAT" || echo "OLD_FORMAT"
52
- ```
53
- - If `NEW_FORMAT` → proceed normally.
54
- - If `OLD_FORMAT` (or file is empty / does not exist) → silently migrate before proceeding:
55
- a. Write `crews/{name}/_memory/memories.md` with the new empty-sections format (do NOT attempt to salvage content from the old file — reset unconditionally):
56
- ```markdown
57
- # Crew Memory: {crew-name}
58
-
59
- ## Estilo de Escrita
60
-
61
- ## Design Visual
62
-
63
- ## Estrutura de Conteúdo
64
-
65
- ## Proibições Explícitas
66
-
67
- ## Técnico (específico do crew)
68
- ```
69
- (Use the crew's display name for `{crew-name}`, and the crew code for `{name}` in file paths — they refer to the same crew.)
70
- b. Check if `crews/{name}/_memory/runs.md` exists:
71
- ```bash
72
- test -f crews/{name}/_memory/runs.md && echo "EXISTS" || echo "MISSING"
73
- ```
74
- If `MISSING`, create it with:
75
- ```markdown
76
- # Run History: {crew-name}
77
-
78
- | Data | Run ID | Tema | Output | Score | Resultado |
79
- |------|--------|------|--------|-------|-----------|
80
- ```
81
- - Do NOT inform the user or pause execution for this migration — it is transparent.
82
-
83
- 2. Read `crews/{name}/pipeline/pipeline.yaml` for the pipeline definition
84
- 3. **Resolve skills**: Read `crew.yaml` → `skills` section. For each non-native skill (anything other than web_search, web_fetch):
85
- a. Verify `skills/{skill}/SKILL.md` exists
86
- - If missing → ask user: "Skill '{skill}' is not installed. Install now? (y/n)"
87
- - If yes → read `_opencrew/core/skills.engine.md`, follow Operation 2 (Install)
88
- - If no → **ERROR**: stop pipeline
89
- b. Read SKILL.md, parse frontmatter for type
90
- c. If type: mcp, verify MCP is configured in `.claude/settings.local.json`
91
- - If missing → **ERROR**: "Skill '{skill}' MCP not configured. Reinstall the skill."
92
- All skills must resolve successfully before the pipeline starts (fail fast).
93
- 4. **Model tiers**: Individual steps declare their own `model_tier` in their frontmatter (`fast` or `powerful`), set by the Architect at crew creation time based on the crew's tier (Express/Standard/Full).
94
- - Read `crew.yaml` → `crew.tier` field to understand the crew's depth level:
95
- - `express`: all steps use `model_tier: fast` by default
96
- - `standard`: mixed — research/data steps use `fast`, creative/review steps use `powerful`
97
- - `full`: all steps use `model_tier: powerful` by default
98
- - If a step has its own `model_tier` in frontmatter → step-level override takes priority over crew-level default.
99
- - If neither crew tier nor step model_tier is set → default to `powerful` at dispatch.
100
- 5. Inform the user that the crew is starting:
101
- ```
102
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
103
- 🚀 Running crew: {crew name}
104
- ⚡ Tier: {tier from crew.yaml — express / standard / full}
105
- 📋 Pipeline: {number of steps} steps
106
- 🤖 Agents: {list agent names with icons}
107
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
108
- ```
109
- 5b. **Initialize run folder**: Generate a unique run ID for this execution:
110
- - Format: `YYYY-MM-DD-HHmmss` using the current timestamp (e.g. `2026-03-03-143022`)
111
- - Check if `crews/{name}/output/{run_id}/` already exists
112
- - If it does (sub-second collision), append `-2`, `-3`, etc. until the folder does not exist
113
- - Create the folder using Bash: `mkdir -p crews/{name}/output/{run_id}`
114
- - Store `run_id` in working memory for this run — it will be used for ALL output paths
115
- 6. **Initialize state.json** (only if `dashboard_enabled` — see step 1a; otherwise skip this entire step, including all sub-steps below):
116
- - **IMPORTANT**: When enabled, write to `crews/{name}/state.json` before every step and after every handoff, as described throughout this document. When `dashboard_enabled` is false, never create, write, or delete this file.
117
- - Create `state.json` from scratch:
118
- a. Read `crews/{name}/crew-party.csv` — for each agent row (skip header), extract:
119
- - `id`: take the `path` column, strip `./agents/` prefix and `.agent.md` suffix
120
- (e.g. `./agents/researcher.agent.md` → `researcher`)
121
- - `name`: use the `displayName` column
122
- - `icon`: use the `icon` column
123
- b. Assign desk positions by agent order (0-based index):
124
- - `col = (index % 3) + 1`
125
- - `row = floor(index / 3) + 1`
126
- (index 0 → col:1 row:1, index 1 → col:2 row:1, index 2 → col:3 row:1, index 3 → col:1 row:2, etc.)
127
- c. Read `crews/{name}/crew.yaml` — count items in `pipeline.steps` for `total`
128
- d. Write `crews/{name}/state.json` with the Write tool:
129
- ```json
130
- {
131
- "crew": "{crew code from crew.yaml}",
132
- "status": "idle",
133
- "step": { "current": 0, "total": {step count from c}, "label": "" },
134
- "agents": [
135
- {
136
- "id": "{agent id}",
137
- "name": "{agent displayName}",
138
- "icon": "{agent icon}",
139
- "status": "idle",
140
- "desk": { "col": {col from b}, "row": {row from b} }
141
- }
142
- ],
143
- "handoff": null,
144
- "startedAt": null,
145
- "updatedAt": "{ISO timestamp now}"
146
- }
147
- ```
148
- Include one entry per agent, in crew-party.csv order.
149
-
150
- ## Execution Rules
151
-
152
- ### Agent Loading (for inline and subagent steps)
153
-
154
- Before executing any step that references an agent:
155
- 1. Read the agent's row from crew-party.csv for quick persona reference
156
- 2. Read the FULL agent file from the crew's agents/ directory (path comes from crew-party.csv)
157
- - The file uses YAML frontmatter for metadata and markdown body for depth
158
- - The markdown body contains: Operational Framework, Output Examples, Anti-Patterns, Voice Guidance
159
- - The file is always complete — the Build phase already merged any `extends:` base agent
160
- - If the frontmatter has `extends: {base-id}`, the agent was generated from `_opencrew/agents/{base-id}.agent.md` — the lineage is preserved for documentation but requires no runtime resolution
161
- 3. When executing the step, the agent's full definition informs behavior:
162
- - Follow the Operational Framework's process steps
163
- - Use Output Examples as quality reference
164
- - Avoid Anti-Patterns listed in the agent definition
165
- - Apply Voice Guidance (vocabulary always/never use, tone rules)
166
- 5. **Inject format context**: Check if the current step's frontmatter contains a `format:` field.
167
- If present:
168
- a. **Export formats** — if format is one of `pdf`, `csv`, or `formatted-post`:
169
- - Read `_opencrew/core/prompts/export.prompt.md`
170
- - Parse the YAML frontmatter to extract the `name` field
171
- - Extract the Markdown body (everything after the YAML frontmatter closing `---`)
172
- - Append to the agent's context, before skill instructions:
173
- ```
174
- --- EXPORT FORMAT: {format} ---
175
-
176
- {export.prompt.md markdown body}
177
- ```
178
- - The agent must follow the export process for the specified format — read the input file,
179
- transform the content, and write the output file in the target format.
180
- - Skip the best-practices lookup below for export formats.
181
- b. **Content formats** — otherwise, read `_opencrew/core/best-practices/{format}.md` (e.g., `_opencrew/core/best-practices/instagram-feed.md`)
182
- - If the file does not exist → **WARNING**: "Format '{format}' not found in _opencrew/core/best-practices/. Skipping format injection." Continue without format.
183
- c. Parse the YAML frontmatter to extract the `name` field
184
- d. Extract the Markdown body (everything after the YAML frontmatter closing `---`)
185
- e. Append to the agent's context, before skill instructions:
186
- ```
187
- --- FORMAT: {name from frontmatter} ---
188
-
189
- {format file markdown body}
190
- ```
191
- If the step has no `format:` field, skip this step entirely (backward compatible).
192
- 6. **Inject skill context (Two-Tier)**:
193
- a. Build a Tier 1 skill index from each declared skill's frontmatter `name` and `description` (~30 tokens per skill)
194
- b. Append the index after format injection:
195
- ```
196
- --- AVAILABLE SKILLS ---
197
- - {skill-id}: {description} (type: {type})
198
- ```
199
- c. If the step's frontmatter contains `skills_needed: [...]`, load Tier 2 (full SKILL.md body) for those skills immediately
200
- d. Otherwise, Tier 2 is loaded on-demand when the agent invokes a skill during execution
201
- e. See `_opencrew/core/skills.engine.md` Operation 6 for full details
202
-
203
- The final agent context composition order is:
204
- ```
205
- Agent (.agent.md) → Crew Memory Rules → Platform Best Practices → Skill Index (Tier 1) → Skill Instructions (Tier 2, on-demand)
206
- ```
207
-
208
- 4. **Inject crew memory rules**: Before building the agent's execution prompt, inject accumulated correction rules from `crews/{name}/_memory/memories.md`:
209
- a. Read `memories.md` and extract:
210
- - `## Proibições Explícitas` — hard blocks, injected as NUNCA rules
211
- - `## Regras de Ouro` — promoted patterns, injected as SEMPRE rules
212
- - `## Estilo de Escrita` — writing style rules relevant to creator agents
213
- - `## Design Visual` — visual rules relevant to designer agents
214
- b. Build the injection block:
215
- ```
216
- --- CREW MEMORY (accumulated from past runs) ---
217
-
218
- NUNCA:
219
- {list of Proibições Explícitas, one per line}
220
-
221
- SEMPRE:
222
- {list of Regras de Ouro, one per line}
223
-
224
- PREFERÊNCIAS:
225
- {relevant rules from Estilo de Escrita and Design Visual for this agent}
226
- ```
227
- c. Inject this block immediately after the agent definition and BEFORE format/skill context.
228
- d. Skip sections that are empty or not relevant to the current agent (e.g., skip Design Visual for a writer agent).
229
- e. If `memories.md` has no accumulated rules → skip injection entirely (no empty block).
230
-
231
- ### Context Compression (Summary-Based Handoff)
232
-
233
- To prevent linear token growth across multi-agent pipelines, apply context compression
234
- when passing prior agents' outputs as context:
235
-
236
- 1. **TL;DR extraction**: After each agent completes, check if its output contains a `## TL;DR` section.
237
- If present, extract and store it separately as the agent's summary.
238
- ```bash
239
- grep -q "^## TL;DR" "{outputFile}" && echo "HAS_TLDR" || echo "NO_TLDR"
240
- ```
241
-
242
- 2. **Compressed context assembly**: When preparing context for Agent N:
243
- - Include **TL;DR summaries** from Agents 1 through N-2 (all agents except the direct predecessor)
244
- - Include the **full output** from Agent N-1 (the direct predecessor) — this ensures
245
- the current agent has complete detail from its immediate dependency
246
- - Full outputs from all agents remain saved in `output/{run_id}/` for reference
247
-
248
- 3. **Context format**:
249
- ```
250
- --- PRIOR CONTEXT (Summaries) ---
251
-
252
- ### {Agent 1 Name} — Summary
253
- {TL;DR content from Agent 1}
254
-
255
- ### {Agent 2 Name} — Summary
256
- {TL;DR content from Agent 2}
257
-
258
- --- PREVIOUS STEP (Full Output) ---
259
-
260
- {Complete output from Agent N-1}
261
- ```
262
-
263
- 4. **Fallback**: If an agent's output does NOT contain a `## TL;DR` section,
264
- use the first 500 characters of the output as an auto-summary.
265
- Going forward, the Architect should ensure all agent definitions include
266
- a TL;DR requirement in their output instructions.
267
-
268
- 5. **Single-agent crews**: If the pipeline has only 1 step, this rule does not apply.
269
-
270
- 6. **Backward compatibility**: If the crew was created before this feature,
271
- the runner falls back to passing full outputs (current behavior) when no
272
- TL;DR sections are found in any prior output.
273
-
274
- ### Task-Based Agent Execution
275
-
276
- When an agent's `.agent.md` frontmatter contains a `tasks:` field:
277
-
278
- 1. **Load task list**: Read the `tasks:` array from the agent's frontmatter
279
- - Each entry is a relative path to a task file (e.g., `tasks/analyze-source.md`)
280
- - Tasks execute in the order listed
281
-
282
- 2. **For each task in sequence**:
283
- a. Read the task file from the agent's directory (e.g., `crews/{crew-name}/agents/{agent}/tasks/{task}.md`)
284
- b. Construct the execution prompt:
285
- - Agent persona + principles (from agent.md — fixed across all tasks)
286
- - Task description and process (from task file)
287
- - Task output format (from task file)
288
- - Task quality criteria and veto conditions (from task file)
289
- - Input: For the first task, use the step's input. For subsequent tasks, use the previous task's output.
290
- c. Execute the task (inline or subagent, matching the step's execution mode)
291
- d. Collect the task output
292
- e. Check task veto conditions (same enforcement as step veto conditions below)
293
-
294
- 3. **Final output**: The output of the LAST task in the chain becomes the step's output
295
- - Apply the Output Path Transformation (Steps 1 and 2: run_id injection + version folder) to the `outputFile` path before saving — this applies regardless of whether the step runs as `execution: inline` or `execution: subagent`
296
- - Save to the **transformed** outputFile path
297
- - This is what the next step (or checkpoint) receives
298
-
299
- 4. **Progress reporting**: For inline execution, announce each task:
300
- ```
301
- {icon} {Agent Name} — Task {N}/{total}: {task name}...
302
- ```
303
-
304
- 5. **Backward compatibility**: If the agent's frontmatter does NOT contain a `tasks:` field,
305
- execute the agent monolithically as before (current behavior unchanged).
306
-
307
- ### Output Path Transformation
308
-
309
- Before saving any output file in a step, apply these rules to determine the final path:
310
-
311
- #### Step 1 — Insert run_id
312
-
313
- - If the path starts with `crews/{name}/output/`, insert `{run_id}/` immediately after `output/`
314
- - Example: `crews/carousel/output/slides/draft.md` → `crews/carousel/output/2026-03-03-143022/slides/draft.md`
315
- - Example: `crews/carousel/output/angles-brief.yaml` → `crews/carousel/output/2026-03-03-143022/angles-brief.yaml`
316
- - If the path does NOT start with `crews/{name}/output/`, leave it unchanged
317
-
318
- #### Step 2 — Insert version folder
319
-
320
- Apply to every path that was transformed in Step 1:
321
-
322
- 1. Determine the **output group** = the parent directory of the file (after Step 1 transformation)
323
- - Example: `crews/carousel/output/2026-03-03-143022/slides/draft.md` → group is `crews/carousel/output/2026-03-03-143022/slides/`
324
- - Example: `crews/carousel/output/2026-03-03-143022/angles-brief.yaml` → group is `crews/carousel/output/2026-03-03-143022/`
325
-
326
- 2. Detect existing versions for this group using Bash:
327
- ```bash
328
- ls -1 crews/{name}/output/{run_id}/{relative-group}/ 2>/dev/null | grep -E '^v[0-9]+$' | sort -V | tail -1
329
- ```
330
- - If the command returns a version (e.g. `v2`) → use `v3`
331
- (Always increment the highest version found, even if lower versions have gaps — e.g. if `v1` and `v3` exist, use `v4`)
332
- - If the command returns nothing (no versions yet) → use `v1`
333
- (`{relative-group}` is the portion of the group path after `crews/{name}/output/{run_id}/`, e.g. `slides/` or empty string for root-level files)
334
-
335
- 3. Insert the version folder immediately before the filename:
336
- - `crews/carousel/output/2026-03-03-143022/slides/draft.md` → `crews/carousel/output/2026-03-03-143022/slides/v1/draft.md`
337
- - `crews/carousel/output/2026-03-03-143022/angles-brief.yaml` → `crews/carousel/output/2026-03-03-143022/v1/angles-brief.yaml`
338
-
339
- 4. **Cache per group**: within a single step execution, once a version is determined for a group, reuse it for all subsequent files in that same group. Do not re-run the `ls` per file.
340
- If the same file path is written twice within a step, both writes go to the same versioned path (the second write overwrites the first within that version).
341
-
342
- Apply this transformation consistently for every write in this step.
343
-
344
- ### For each pipeline step:
345
-
346
- 0. **Update dashboard** (only if `dashboard_enabled`; otherwise skip to step 1). Write `crews/{name}/state.json` using the Write tool. Use this content:
347
- ```json
348
- {
349
- "crew": "{crew code from crew.yaml}",
350
- "status": "running",
351
- "step": {
352
- "current": {1-based index of this step},
353
- "total": {total steps in pipeline},
354
- "label": "{step id or label}"
355
- },
356
- "agents": [
357
- {
358
- "id": "{agent id}",
359
- "name": "{agent displayName}",
360
- "icon": "{agent icon}",
361
- "status": "{working if this is the current step's agent, done if already completed, idle otherwise}",
362
- "desk": {preserve existing desk positions from state.json — do not change col/row}
363
- }
364
- ],
365
- "handoff": {preserve existing handoff object, or null if this is the first step},
366
- "startedAt": "{ISO timestamp — set on the first step only, then preserve from existing state.json on subsequent steps}",
367
- "updatedAt": "{ISO timestamp now}"
368
- }
369
- ```
370
-
371
- 1. **Pre-Step Input Validation** — MANDATORY. If the step's frontmatter declares an `inputFile`, validate that the input exists before executing the step. Run via Bash tool:
372
- ```bash
373
- test -s "{transformed inputFile path}" && echo "VALIDATION:PASS" || echo "VALIDATION:FAIL"
374
- ```
375
- - Apply the Output Path Transformation (Step 1: run_id injection) to the `inputFile` path before running the check.
376
- - If the Bash output contains `VALIDATION:PASS` → proceed to execute the step.
377
- - If the Bash output contains `VALIDATION:FAIL` → do NOT execute the step. Present to user:
378
- ```
379
- ⚠️ Input for {Agent Name} not found: {path}
380
- The previous step may have failed to produce output.
381
-
382
- 1. Skip step and continue
383
- 2. Abort pipeline
384
- ```
385
- Wait for user choice before proceeding. No retry — if the input doesn't exist, re-executing this step won't create it. The problem is upstream.
386
- - If the step does not declare an `inputFile` → skip this validation entirely.
387
- - Checkpoint steps (`type: checkpoint`) are exempt — they receive input from the user, not from files.
388
-
389
- 2. **Read the step file** completely: `crews/{name}/pipeline/steps/{step-file}.md`
390
- 3. **Check execution mode** from the step's frontmatter:
391
-
392
- #### If `execution: subagent`
393
- - Inform user: `🔍 {Agent Name} is working in the background...`
394
- - Read the step's `model_tier` frontmatter field (if present).
395
- Valid values: `fast` or `powerful`. If absent or any other value: default to `powerful`.
396
- - **Before building the subagent prompt**: Apply the Output Path Transformation (Step 1: run_id injection + Step 2: version folder) to all output paths referenced in the step file. Store the transformed path(s) in working memory — they will be used both in the prompt and in post-completion verification. Never pass raw paths from the step file to the subagent.
397
- - Use the Task tool to dispatch the step as a subagent:
398
- - If `model_tier: fast`: use the fastest/lightest model available in your current IDE.
399
- - If `model_tier: powerful` or absent/invalid: use the default model (no model override needed)
400
- - In the Task prompt, include:
401
- - The full agent persona from the party CSV
402
- - The full agent `.agent.md` content (persona, principles, voice guidance, anti-patterns)
403
- - If the agent has tasks: include ALL task files in order with instructions to execute sequentially, piping output from each task to the next
404
- - If the agent has no tasks: include the step instructions and operational framework as before
405
- - The veto conditions from the step file (agent should self-check before completing)
406
- - The company context
407
- - The crew memory
408
- - The **transformed** path to save output (e.g., `crews/{name}/output/2026-03-20-140736/slides/v1/draft.md`)
409
- - Wait for the subagent to complete
410
- - Inform user: `✓ {Agent Name} completed`
411
- - Proceed to Post-Step Output Validation (below) before advancing.
412
-
413
- #### If `execution: inline`
414
- - Switch to the agent's persona (read from party CSV)
415
- - Announce: `{icon} {Agent Name} is working...`
416
- - Follow the step instructions
417
- - Present output directly in the conversation
418
- - Save output to the specified output file — apply the Output Path Transformation (Steps 1 and 2) to the path before writing. Do not write to the raw path from the step file.
419
- - Proceed to Post-Step Output Validation (below) before advancing.
420
-
421
- #### If `type: checkpoint`
422
- - Present the checkpoint message to the user
423
- - If the checkpoint requires a choice (numbered list), present options as a numbered list
424
- - **Always include the file path** of any generated content the user needs to review. Example: "Review the content at `crews/{name}/output/{run_id}/v1/content.md` and let me know if it looks good."
425
- - Wait for user input before proceeding
426
- - Save the user's choice/response for the next step
427
- - **If the step frontmatter contains `outputFile`**: after collecting the user's full response,
428
- apply the Output Path Transformation **Step 1 only** (run_id injection — skip Step 2, version folder) to the `outputFile` path, then write the response to the transformed path using the Write tool before moving to the next step. Checkpoint files are user input captures, not versioned output — Step 2 does not apply here, regardless of the general "every write" rule in the Output Path Transformation section above.
429
- Use this format:
430
- ```
431
- # Research Focus
432
-
433
- **Topic:** {user's typed topic}
434
- **Time Range:** {selected time range label, e.g., "Últimos 7 dias"}
435
- **Date:** {today's date in YYYY-MM-DD format}
436
- ```
437
- This file is the `inputFile` for the researcher step that follows.
438
-
439
- ### Post-Step Output Validation
440
-
441
- After a step produces output (subagent or inline) and BEFORE Veto Condition Enforcement, the runner MUST validate that the declared output files exist and are non-empty. This is a binary, non-negotiable gate — the runner does NOT proceed on memory or assumption, only on bash output.
442
-
443
- **If the step declares an `outputFile`** (single or multiple), run via Bash tool for EACH output file:
444
-
445
- ```bash
446
- test -s "{transformed outputFile path}" && echo "VALIDATION:PASS" || echo "VALIDATION:FAIL"
447
- ```
448
-
449
- Use the **stored transformed path** (after Output Path Transformation Steps 1 and 2), not the raw path from the step file.
450
-
451
- **Rules:**
452
- - If ALL output files return `VALIDATION:PASS` → proceed to Veto Condition Enforcement.
453
- - If ANY output file returns `VALIDATION:FAIL`:
454
- 1. **Retry once**: re-execute the entire step with the same input and context.
455
- 2. After re-execution, run the validation again for all output files.
456
- 3. If second attempt returns `VALIDATION:PASS` for all files → proceed normally.
457
- 4. If second attempt still has ANY `VALIDATION:FAIL` → present to user:
458
- ```
459
- ⚠️ {Agent Name}'s output was not generated: {path}
460
-
461
- 1. Retry step
462
- 2. Skip step and continue
463
- 3. Abort pipeline
464
- ```
465
- Wait for user choice before proceeding.
466
- - If the step does not declare an `outputFile` (e.g., steps that only produce inline console output) → skip output validation.
467
- - Checkpoint steps (`type: checkpoint`) are exempt — their output is the user's response, not a file.
468
-
469
- **IMPORTANT**: Do NOT rely on reading the file with the Read tool to "verify" output. The Read tool returns content that can be misinterpreted. Use ONLY the bash `test -s` command — its output is binary and cannot be hallucinated.
470
-
471
- ### Output Contract Validation
472
-
473
- If the step's frontmatter declares an `output_contract:` field, apply structured validation
474
- AFTER the basic file existence check passes:
475
-
476
- 1. **Required sections check**: If `output_contract.required_sections` is defined,
477
- verify each required section exists in the output file:
478
- ```bash
479
- grep -c "^## " "{transformed outputFile path}" | xargs -I {} test {} -ge {min_sections} && echo "SECTIONS:PASS" || echo "SECTIONS:FAIL"
480
- ```
481
-
482
- 2. **TL;DR check**: If the output contract requires a TL;DR section:
483
- ```bash
484
- grep -q "^## TL;DR" "{transformed outputFile path}" && echo "TLDR:PASS" || echo "TLDR:FAIL"
485
- ```
486
-
487
- 3. **If any check fails**:
488
- - Present to user: "⚠️ Output from {Agent Name} is incomplete: {which checks failed}"
489
- - Options as numbered list:
490
- 1. Accept anyway and continue
491
- 2. Retry step (re-execute the agent)
492
- 3. Abort pipeline
493
-
494
- 4. **If no `output_contract` is defined**, skip this validation entirely (backward compatible).
495
-
496
- Example `output_contract` in step frontmatter:
497
- ```yaml
498
- output_contract:
499
- required_sections:
500
- - "Fontes Pesquisadas"
501
- - "Principais Descobertas"
502
- - "TL;DR"
503
- min_sections: 3
504
- ```
505
-
506
- ### Veto Condition Enforcement
507
-
508
- After an agent completes a step (before moving to the next step):
509
-
510
- 1. Check if the step file has a `## Veto Conditions` section
511
- 2. If yes, evaluate each veto condition against the agent's output:
512
- - Read the output that was just produced
513
- - Check each condition (e.g., "slides exceed 30 words", "no CTA", "missing sources")
514
- 3. If ANY veto condition is triggered:
515
- - Inform user: "⚠️ {Agent Name}'s output triggered a veto: {condition}"
516
- - Ask the agent to fix the specific issue (re-execute with targeted correction)
517
- - Maximum 2 veto fix attempts per step
518
- - After 2 failed attempts, present to user for manual decision
519
- 4. If no veto conditions triggered: proceed to next step
520
-
521
- This creates an internal quality loop BEFORE the reviewer sees the content,
522
- catching obvious issues early and reducing review cycle waste.
523
-
524
- ### Review Loops
525
-
526
- When a step has `on_reject: {step-id}`:
527
- - Track the review cycle count
528
- - If reviewer rejects, go back to the referenced step
529
- - Pass reviewer feedback to the writer agent
530
- - If max_review_cycles reached, present to user for manual decision
531
-
532
- ### Dashboard Handoff (between steps)
533
-
534
- Only if `dashboard_enabled` (otherwise skip this entire section). After a step
535
- completes output and there IS a next step:
536
-
537
- 1. **Write delivering state** — Write `crews/{name}/state.json` with:
538
- - Current step's agent: `"status": "delivering"`
539
- - Next step's agent: `"status": "idle"`
540
- - All other agents unchanged
541
- - Pipeline `"status": "running"`
542
- - Add or update `"handoff"`:
543
- ```json
544
- "handoff": {
545
- "from": "{current agent id}",
546
- "to": "{next agent id}",
547
- "message": "{one-sentence summary of what was produced, written in the user's language}",
548
- "completedAt": "{ISO timestamp now}"
549
- }
550
- ```
551
- - `"updatedAt"`: now
552
-
553
- 2. _(No delay — proceed immediately to working state)_
554
-
555
- 2. **Write working state** — Write `crews/{name}/state.json` again with:
556
- - Current agent: `"status": "done"`
557
- - Next agent: `"status": "working"`
558
- - Keep the `"handoff"` object from step 1 unchanged
559
- - `"updatedAt"`: now
560
-
561
- ### Step Execution Order (Summary)
562
-
563
- For reference, the complete execution order for each pipeline step is:
564
-
565
- ```
566
- 0. Dashboard update (state.json) — only if dashboard_enabled
567
- 1. Pre-Step Input Validation (bash gate)
568
- 2. Read step file
569
- 3. Check execution mode and execute (subagent / inline / checkpoint)
570
- 4. Post-Step Output Validation (bash gate)
571
- 5. Veto Condition Enforcement
572
- 6. Dashboard Handoff (to next step) — only if dashboard_enabled
573
- ```
574
-
575
- Steps 1 and 4 are binary bash gates. If either fails, the pipeline does NOT advance — the user is consulted.
576
-
577
- ### After Pipeline Completion
578
-
579
- 1. Save final output to `crews/{name}/output/{run_id}/{filename}.md`
580
- (The run folder was created during initialization — no separate date subfolder needed)
581
- 1b. **Update dashboard** (only if `dashboard_enabled`; otherwise skip to step 2 below). Write `crews/{name}/state.json` with:
582
- - `"status": "completed"`
583
- - All agents: `"status": "done"`
584
- - `"updatedAt"`: now
585
- - `"completedAt"`: now
586
- - `"startedAt"`: preserve from existing `state.json`
587
- - Keep existing `"handoff"` object
588
-
589
- ### Post-Completion Cleanup (only if `dashboard_enabled`)
590
-
591
- After writing the final "completed" state to `crews/{name}/state.json`:
592
-
593
- 1. Add the `completedAt` field (or `failedAt` if status is `failed`) with the current ISO timestamp
594
- 2. Copy `state.json` to the run output folder for permanent history:
595
- ```bash
596
- cp crews/{name}/state.json crews/{name}/output/{run_id}/state.json
597
- ```
598
- 3. Leave the working copy of `crews/{name}/state.json` in place — do not delete it and
599
- do not add an artificial delay. A dashboard watching the file already sees the
600
- "completed" status the moment it's written; the next run's initialization (step 6)
601
- overwrites this file from scratch. There is nothing to clean up.
602
-
603
- This archives the run state for the `runs` command while keeping crew history available.
604
-
605
- 2. **Update crew memory** — write to BOTH files (runs after Post-Completion Cleanup above):
606
-
607
- ### 2a. Update `memories.md` (living preferences)
608
-
609
- Read `crews/{name}/_memory/memories.md` in full. Then identify candidates from this run: **only explicit user feedback** — approvals with comments, rejections with reasons, direct requests ("prefiro X", "não quero Y"). Never infer preferences.
610
-
611
- For each candidate:
612
- - If an equivalent memory already exists and is compatible → skip (no duplicate)
613
- - If an equivalent memory exists but contradicts the new item → replace with the newer version
614
- - If no equivalent exists → add to the correct semantic section:
615
- - Writing style choices → `## Estilo de Escrita`
616
- - Visual/design preferences → `## Design Visual`
617
- - Content structure choices → `## Estrutura de Conteúdo`
618
- - Explicit rejections or prohibitions → `## Proibições Explícitas`
619
- - Crew-specific technical patterns → `## Técnico (específico do crew)`
620
-
621
- **Never write to `memories.md`:**
622
- - Runner inferences ("usuário parece preferir X")
623
- - Run scores, review grades, output file paths, topics from past runs
624
-
625
- **Technical routing:** For any technical learning (bugs, workarounds, API behavior):
626
- - If it affects any crew (Playwright bugs, OS rendering quirks, API limits) → write to the appropriate `_opencrew/core/best-practices/` file instead of `memories.md`
627
- - If it is specific to this crew's output type or toolchain → add to `## Técnico (específico do crew)` following the dedup rules above
628
-
629
- After applying all candidates, write the updated `memories.md`.
630
-
631
- If no candidates are found (the run had no explicit user feedback), skip writing `memories.md` entirely — do not write an unmodified copy. Always proceed to step 2b regardless.
632
-
633
- ### 2b. Prepend to `runs.md` (reverse-chronological log — newest run first)
634
-
635
- If `crews/{name}/_memory/runs.md` does not exist, create it first with:
636
- ```markdown
637
- # Run History: {crew-name}
638
-
639
- | Data | Run ID | Tema | Output | Score | Resultado |
640
- |------|--------|------|--------|-------|-----------|
641
- ```
642
- Then proceed to prepend the new row.
643
-
644
- Read `crews/{name}/_memory/runs.md`. Prepend one new row to the table (immediately after the header row), with:
645
- - `Data`: today's date in YYYY-MM-DD format
646
- - `Run ID`: the `run_id` for this execution
647
- - `Tema`: the topic or user request from this run (1 sentence max)
648
- - `Output`: brief description of what was generated (e.g., "Carrossel 9 slides", "Thread 7 posts")
649
- - `Score`: `{approved}/{total}` agent outputs approved without corrections (e.g., `4/5`)
650
- - `Resultado`: one of — `Aprovado` / `Rejeitado` / `Publicado` / `Abortado`
651
-
652
- No other data.
653
-
654
- The `Score` column tracks how many agent outputs were approved by the user without corrections in this run. Count only explicit checkpoint approvals (not "skip" or "continue"). Format: `{approved}/{total checkpoints}` (e.g., `4/5` means 4 of 5 agent outputs were approved as-is).
655
-
656
- ### 2c. Post-Run Reflection (pattern detection)
657
-
658
- After updating `memories.md` and `runs.md`, run a reflection pass. This is a lightweight analysis — not a full agent execution, just pattern matching on the run's feedback and past memory.
659
-
660
- 1. **Collect this run's corrections**: From checkpoint responses, gather every user rejection or correction. A correction is:
661
- - A rejected output with a reason ("tom muito informal", "cor não combina", "fonte sem data")
662
- - A modification request during checkpoint ("muda o título para X", "usa azul em vez de verde")
663
-
664
- 2. **Look for recurrence**: Compare each correction against past runs recorded in `memories.md`:
665
- - Search `memories.md` for similar patterns (same category, same agent, same type of correction)
666
- - Count: how many past runs have a correction matching this pattern?
667
- - A "match" means the same agent + same type of error (e.g., "redator + tom informal", "designer + cores saturadas")
668
-
669
- 3. **Promote to Regra de Ouro**: If the SAME pattern appears in **3 or more runs** (including this one):
670
- a. Add a new entry under `## Regras de Ouro` in `memories.md`:
671
- ```markdown
672
- ## Regras de Ouro (promovidas após 3+ ocorrências)
673
-
674
- - **{Agent role}**: SEMPRE {correct behavior}. {Why — grounded in user feedback}.
675
- (Runs: #{run1}, #{run2}, #{run3})
676
- ```
677
- Example:
678
- ```markdown
679
- - **Redator**: SEMPRE verificar se o CTA contém link rastreável antes de finalizar.
680
- (Runs: #2026-08-01-143022, #2026-08-05-091530, #2026-08-10-160845)
681
- ```
682
- b. Remove the individual entries from their original sections (`## Estilo de Escrita`, `## Design Visual`, etc.) — the Regra de Ouro replaces them.
683
- c. Display to the user:
684
- ```
685
- 💡 Regra de Ouro detectada:
686
- "{correct behavior}" aconteceu 3 vezes.
687
- Vou aplicar automaticamente a partir de agora.
688
- ```
689
-
690
- 4. **Mark improvement**: If a previously recurring error did NOT happen this run:
691
- - Add a `✅` marker to the Regra de Ouro entry: `✅ **Redator**: SEMPRE ...`
692
- - This tracks that the crew is improving — the rule is working.
693
-
694
- 5. **Bail out early**: If this run had zero corrections (all checkpoints approved), skip the entire reflection — nothing to learn.
695
-
696
- 6. **Reflection budget**: Maximum 30 seconds of analysis. If the crew has a long history (>20 past runs), sample the most recent 10 runs for pattern matching. This is a quick scan, not an exhaustive audit.
697
-
698
- 3. Present completion summary:
699
- ```
700
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
701
- ✅ Pipeline complete!
702
- 📁 Run folder: crews/{name}/output/{run_id}/
703
- 📄 Output saved to: {output path}
704
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
705
-
706
- What would you like to do?
707
- ● Run again (new topic)
708
- ○ Edit this content
709
- ○ Back to menu
710
- ```
711
-
712
- ## Error Handling
713
-
714
- - If a subagent fails, retry once. If it fails again, inform the user and offer to skip the step or abort.
715
- - If a step file is missing, inform the user and suggest running `/opencrew edit {crew}` to fix.
716
- - If company.md is empty, stop and redirect to onboarding.
717
- - Never continue past a checkpoint without user input.
718
-
719
- ## Pipeline State
720
-
721
- Track pipeline state in memory during execution:
722
- - Run ID (run_id) — the output subfolder name for this execution
723
- - Current step index
724
- - Outputs from each completed step (file paths)
725
- - User choices at checkpoints
726
- - Review cycle count
727
- - Start time
728
-
729
- This state does NOT persist to disk — it exists only during the current run.
1
+ # opencrew Pipeline Runner
2
+
3
+ > **SHARED FILE** — applies to ALL IDEs. Do not add IDE-specific logic here.
4
+ > For IDE-specific behavior, add entries to `src/lib/ides.js` in the source package.
5
+
6
+ You are the Pipeline Runner. Your job is to execute a crew's pipeline step by step.
7
+
8
+ ## Initialization
9
+
10
+ Before starting execution:
11
+
12
+ 1. You have already loaded:
13
+ - The crew's `crew.yaml` (passed to you by the opencrew skill)
14
+ - The crew's `crew-party.csv` (all agent personas)
15
+ - Company context from `_opencrew/_memory/company.md`
16
+ - Crew memory from `crews/{name}/_memory/memories.md`
17
+ - User preferences from `_opencrew/_memory/preferences.md`
18
+
19
+ 1a. **Check the Dashboard toggle** — the visual dashboard (`state.json` writes) is an
20
+ optional, opt-in feature that most installs never use (it requires running the
21
+ separate dashboard app from source — see README). Scan the already-loaded
22
+ `preferences.md` for a `Dashboard:` field:
23
+ - If it reads `Dashboard: enabled` → set `dashboard_enabled = true` for this run.
24
+ - Otherwise (`disabled`, missing, or preferences.md not configured yet) →
25
+ set `dashboard_enabled = false`. This is the default.
26
+ Store `dashboard_enabled` in working memory for the rest of this run. Every
27
+ `state.json` read/write instruction in this document is conditional on it —
28
+ when `false`, skip ALL of them; never create, update, or delete
29
+ `crews/{name}/state.json`.
30
+
31
+ > **Note on language**: The structural labels listed below are **fixed PT-BR** and must
32
+ > never be translated — opencrew's primary supported audience is PT-BR (see AGENTS.md →
33
+ > Language Handling). Only the *content* written under these headers follows the user's
34
+ > preferred language.
35
+ >
36
+ > | Fixed PT-BR header | Location | Purpose |
37
+ > |---|---|---|
38
+ > | `## Estilo de Escrita` | `memories.md` | Writing style rules accumulated per crew |
39
+ > | `## Design Visual` | `memories.md` | Visual design preferences per crew |
40
+ > | `## Estrutura de Conteúdo` | `memories.md` | Content structure rules per crew |
41
+ > | `## Proibições Explícitas` | `memories.md` | User bans and hard blocks per crew |
42
+ > | `## Técnico (específico do crew)` | `memories.md` | Technical crew-specific settings |
43
+ > | `Data \| Run ID \| Tema \| Output \| Score \| Resultado` | `runs.md` | Run history table columns |
44
+ >
45
+ > When adding new structural sections to `memories.md` or `runs.md`, keep headers in PT-BR
46
+ > unless the user base expands beyond PT-BR — at that point, discuss a migration strategy
47
+ > (e.g. i18n key mapping) rather than mixing languages in a single file.
48
+
49
+ 1b. **Memory format migration** — After loading `memories.md`, check whether it uses the new format by scanning for the `## Estilo de Escrita` section header:
50
+ ```bash
51
+ [ -f crews/{name}/_memory/memories.md ] && grep -q "## Estilo de Escrita" crews/{name}/_memory/memories.md && echo "NEW_FORMAT" || echo "OLD_FORMAT"
52
+ ```
53
+ - If `NEW_FORMAT` → proceed normally.
54
+ - If `OLD_FORMAT` (or file is empty / does not exist) → silently migrate before proceeding:
55
+ a. Write `crews/{name}/_memory/memories.md` with the new empty-sections format (do NOT attempt to salvage content from the old file — reset unconditionally):
56
+ ```markdown
57
+ # Crew Memory: {crew-name}
58
+
59
+ ## Estilo de Escrita
60
+
61
+ ## Design Visual
62
+
63
+ ## Estrutura de Conteúdo
64
+
65
+ ## Proibições Explícitas
66
+
67
+ ## Técnico (específico do crew)
68
+ ```
69
+ (Use the crew's display name for `{crew-name}`, and the crew code for `{name}` in file paths — they refer to the same crew.)
70
+ b. Check if `crews/{name}/_memory/runs.md` exists:
71
+ ```bash
72
+ test -f crews/{name}/_memory/runs.md && echo "EXISTS" || echo "MISSING"
73
+ ```
74
+ If `MISSING`, create it with:
75
+ ```markdown
76
+ # Run History: {crew-name}
77
+
78
+ | Data | Run ID | Tema | Output | Score | Resultado |
79
+ |------|--------|------|--------|-------|-----------|
80
+ ```
81
+ - Do NOT inform the user or pause execution for this migration — it is transparent.
82
+
83
+ 2. Read `crews/{name}/pipeline/pipeline.yaml` for the pipeline definition
84
+ 3. **Resolve skills**: Read `crew.yaml` → `skills` section. For each non-native skill (anything other than web_search, web_fetch):
85
+ a. Verify `skills/{skill}/SKILL.md` exists
86
+ - If missing → ask user: "Skill '{skill}' is not installed. Install now? (y/n)"
87
+ - If yes → read `_opencrew/core/skills.engine.md`, follow Operation 2 (Install)
88
+ - If no → **ERROR**: stop pipeline
89
+ b. Read SKILL.md, parse frontmatter for type
90
+ c. If type: mcp, verify MCP is configured in `.claude/settings.local.json`
91
+ - If missing → **ERROR**: "Skill '{skill}' MCP not configured. Reinstall the skill."
92
+ All skills must resolve successfully before the pipeline starts (fail fast).
93
+ 4. **Model tiers**: Individual steps declare their own `model_tier` in their frontmatter (`fast` or `powerful`), set by the Architect at crew creation time based on the crew's tier (Express/Standard/Full).
94
+ - Read `crew.yaml` → `crew.tier` field to understand the crew's depth level:
95
+ - `express`: all steps use `model_tier: fast` by default
96
+ - `standard`: mixed — research/data steps use `fast`, creative/review steps use `powerful`
97
+ - `full`: all steps use `model_tier: powerful` by default
98
+ - If a step has its own `model_tier` in frontmatter → step-level override takes priority over crew-level default.
99
+ - If neither crew tier nor step model_tier is set → default to `powerful` at dispatch.
100
+
101
+ 4b. **Pre-Execution Agent Selection** — Decide which agents actually run for this task.
102
+ Run this step ONLY if `crew.yaml` declares an `agent_dependencies:` field (even an
103
+ empty map `{}`). If the field is absent → skip this entire step and run ALL agents
104
+ exactly as before (legacy behavior).
105
+
106
+ When active, in this order:
107
+
108
+ a. **Capture the task** — Determine the user's request for this run:
109
+ - If the run was invoked with a description (e.g. `/opencrew run {name} {description}`),
110
+ use that text as the task.
111
+ - Otherwise ask: `📝 What is the task for this run? Reply in one line.`
112
+ Wait for the user's reply before continuing.
113
+
114
+ b. **Analyze against the decision matrix** — Scan the task text (case-insensitive,
115
+ PT-BR and EN keywords) for the signals below. Start with ALL agents suggested as
116
+ SELECTED (`required`). For each matching signal, find the affected agent(s) in
117
+ `crew-party.csv` by matching the role terms against the agent's `id` and `title`
118
+ (and `displayName` if ambiguous), then apply the suggested status:
119
+
120
+ | Signal in the task | Role terms to match (id / title) | Suggested status |
121
+ |--------------------|----------------------------------|------------------|
122
+ | "já pesquisei", "com base em", "fontes que tenho", "material pronto", "baseado nas fontes", "research already done" | researcher, pesquisad, research | optional |
123
+ | "revise", "melhore", "corrija", "refine", "edite" (sem criar do zero), "improve this draft" | copywriter, redator, writer, criador | optional |
124
+ | "só texto", "sem imagem", "sem visual", "sem arte", "no image" | designer, design, visual | skip |
125
+ | "já revisei", "já foi aprovado", "aprovado por terceiros", "revisão feita", "already reviewed" | reviewer, revisor | optional |
126
+ | "quero só revisar este texto", "apenas revisar", "review only" | researcher AND copywriter | skip |
127
+ | "tenho o conteúdo pronto", "forneço o documento", "docs em anexo", "segue o material", "here is the content" | copywriter, writer, creator | optional |
128
+
129
+ Resolution rules:
130
+ - `optional` = agent stays selected but may be unchecked.
131
+ - `skip` = agent is suggested deselected.
132
+ - Conflicting signals on the same agent → the more restrictive wins (`skip` > `optional`).
133
+ - Never suggest skipping an agent whose output is the run's final deliverable unless the
134
+ signal is explicit.
135
+ - No signal matches → suggest keeping all agents (no change).
136
+
137
+ c. **Present the selection** — IDE-neutral numbered multi-select. List every agent from
138
+ `crew-party.csv` in party order:
139
+ ```
140
+ 🧑‍🤝‍🧑 Which agents should work on this task?
141
+
142
+ Suggested selection:
143
+ 1. [x] {icon} {displayName} ({id}) — {title}
144
+ 2. [x] {icon} {displayName} ({id}) — {title}
145
+ 3. [ ] {icon} {displayName} ({id}) — {title}
146
+ ...
147
+ [x] = suggested selected · [ ] = suggested deselected
148
+
149
+ Reply with the numbers of the agents you want to INCLUDE, separated by commas.
150
+ Example: "1, 2" · Reply "all" to run everyone.
151
+ ```
152
+ Wait for the user's reply. Parse it into `selected_agents`. At least one agent must
153
+ be selected — if the user replies with none, repeat the prompt once.
154
+
155
+ d. **Dependency warnings** — Using `crew.yaml → agent_dependencies`
156
+ (e.g. `copywriter: [researcher]` = copywriter consumes researcher's output):
157
+ for every dependency `dependent → required_agent`, if `dependent` is selected but
158
+ `required_agent` is NOT, warn:
159
+ ```
160
+ ⚠️ {dependent} normally depends on {required_agent}'s output, which you deselected.
161
+
162
+ 1. Re-select {required_agent} (recommended)
163
+ 2. Keep going without it — I will supply the input myself
164
+ 3. Deselect {dependent} too
165
+ ```
166
+ Wait for the user's choice and apply it. If they pick option 2, set
167
+ `missing_dependency = true` in working memory (the existing Pre-Step Input
168
+ Validation recovery — "Skip step and continue / Abort" — then handles any
169
+ downstream gap).
170
+
171
+ e. **Build the filtered step list** — Set `skipped_agents = all party agents − selected_agents`.
172
+ Build `filtered_steps` by walking `pipeline.yaml` in order, keeping a step when:
173
+ - its frontmatter has NO `agent:` field (checkpoints / generic steps), OR
174
+ - its `agent:` value is in `selected_agents`.
175
+ Store `selected_agents`, `skipped_agents`, and `filtered_steps` in working memory for
176
+ the per-step loop (steps 5 and 6 below reflect them).
177
+
178
+ 5. Inform the user that the crew is starting:
179
+ ```
180
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
181
+ 🚀 Running crew: {crew name}
182
+ ⚡ Tier: {tier from crew.yaml — express / standard / full}
183
+ 📋 Pipeline: {count of filtered_steps} steps{if selection active: of {total steps} in pipeline}
184
+ 🤖 Agents: {list SELECTED agent names with icons}
185
+ {if any skipped} ⏭️ Skipped: {list deselected agent names with icons}
186
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
187
+ ```
188
+ When the selection step was skipped (no `agent_dependencies:` in crew.yaml), this is
189
+ identical to today: all agents listed, no Skipped line.
190
+ 5b. **Initialize run folder**: Generate a unique run ID for this execution:
191
+ - Format: `YYYY-MM-DD-HHmmss` using the current timestamp (e.g. `2026-03-03-143022`)
192
+ - Check if `crews/{name}/output/{run_id}/` already exists
193
+ - If it does (sub-second collision), append `-2`, `-3`, etc. until the folder does not exist
194
+ - Create the folder using Bash: `mkdir -p crews/{name}/output/{run_id}`
195
+ - Store `run_id` in working memory for this run — it will be used for ALL output paths
196
+ 6. **Initialize state.json** (only if `dashboard_enabled` — see step 1a; otherwise skip this entire step, including all sub-steps below):
197
+ - **IMPORTANT**: When enabled, write to `crews/{name}/state.json` before every step and after every handoff, as described throughout this document. When `dashboard_enabled` is false, never create, write, or delete this file.
198
+ - Create `state.json` from scratch:
199
+ a. Read `crews/{name}/crew-party.csv` — for each agent row (skip header), extract:
200
+ - `id`: take the `path` column, strip `./agents/` prefix and `.agent.md` suffix
201
+ (e.g. `./agents/researcher.agent.md` → `researcher`)
202
+ - `name`: use the `displayName` column
203
+ - `icon`: use the `icon` column
204
+ b. Assign desk positions by agent order (0-based index):
205
+ - `col = (index % 3) + 1`
206
+ - `row = floor(index / 3) + 1`
207
+ (index 0 → col:1 row:1, index 1 → col:2 row:1, index 2 → col:3 row:1, index 3 → col:1 row:2, etc.)
208
+ c. Read `crews/{name}/crew.yaml` — count items in `pipeline.steps` for `total`
209
+ d. Write `crews/{name}/state.json` with the Write tool:
210
+ ```json
211
+ {
212
+ "crew": "{crew code from crew.yaml}",
213
+ "status": "idle",
214
+ "step": { "current": 0, "total": {step count from c}, "label": "" },
215
+ "agents": [
216
+ {
217
+ "id": "{agent id}",
218
+ "name": "{agent displayName}",
219
+ "icon": "{agent icon}",
220
+ "status": "idle",
221
+ "desk": { "col": {col from b}, "row": {row from b} }
222
+ }
223
+ ],
224
+ "handoff": null,
225
+ "startedAt": null,
226
+ "updatedAt": "{ISO timestamp now}"
227
+ }
228
+ ```
229
+ Include one entry per agent, in crew-party.csv order. For each agent, set
230
+ `"status"` to `"skipped"` if it is in `skipped_agents`, otherwise `"idle"`.
231
+
232
+ ## Execution Rules
233
+
234
+ ### Agent Loading (for inline and subagent steps)
235
+
236
+ Before executing any step that references an agent:
237
+ 1. Read the agent's row from crew-party.csv for quick persona reference
238
+ 2. Read the FULL agent file from the crew's agents/ directory (path comes from crew-party.csv)
239
+ - The file uses YAML frontmatter for metadata and markdown body for depth
240
+ - The markdown body contains: Operational Framework, Output Examples, Anti-Patterns, Voice Guidance
241
+ - The file is always complete — the Build phase already merged any `extends:` base agent
242
+ - If the frontmatter has `extends: {base-id}`, the agent was generated from `_opencrew/agents/{base-id}.agent.md` — the lineage is preserved for documentation but requires no runtime resolution
243
+ 3. When executing the step, the agent's full definition informs behavior:
244
+ - Follow the Operational Framework's process steps
245
+ - Use Output Examples as quality reference
246
+ - Avoid Anti-Patterns listed in the agent definition
247
+ - Apply Voice Guidance (vocabulary always/never use, tone rules)
248
+ 5. **Inject format context**: Check if the current step's frontmatter contains a `format:` field.
249
+ If present:
250
+ a. **Export formats** — if format is one of `pdf`, `csv`, or `formatted-post`:
251
+ - Read `_opencrew/core/prompts/export.prompt.md`
252
+ - Parse the YAML frontmatter to extract the `name` field
253
+ - Extract the Markdown body (everything after the YAML frontmatter closing `---`)
254
+ - Append to the agent's context, before skill instructions:
255
+ ```
256
+ --- EXPORT FORMAT: {format} ---
257
+
258
+ {export.prompt.md markdown body}
259
+ ```
260
+ - The agent must follow the export process for the specified format — read the input file,
261
+ transform the content, and write the output file in the target format.
262
+ - Skip the best-practices lookup below for export formats.
263
+ b. **Content formats** — otherwise, read `_opencrew/core/best-practices/{format}.md` (e.g., `_opencrew/core/best-practices/instagram-feed.md`)
264
+ - If the file does not exist → **WARNING**: "Format '{format}' not found in _opencrew/core/best-practices/. Skipping format injection." Continue without format.
265
+ c. Parse the YAML frontmatter to extract the `name` field
266
+ d. Extract the Markdown body (everything after the YAML frontmatter closing `---`)
267
+ e. Append to the agent's context, before skill instructions:
268
+ ```
269
+ --- FORMAT: {name from frontmatter} ---
270
+
271
+ {format file markdown body}
272
+ ```
273
+ If the step has no `format:` field, skip this step entirely (backward compatible).
274
+ 6. **Inject skill context (Two-Tier)**:
275
+ a. Build a Tier 1 skill index from each declared skill's frontmatter `name` and `description` (~30 tokens per skill)
276
+ b. Append the index after format injection:
277
+ ```
278
+ --- AVAILABLE SKILLS ---
279
+ - {skill-id}: {description} (type: {type})
280
+ ```
281
+ c. If the step's frontmatter contains `skills_needed: [...]`, load Tier 2 (full SKILL.md body) for those skills immediately
282
+ d. Otherwise, Tier 2 is loaded on-demand when the agent invokes a skill during execution
283
+ e. See `_opencrew/core/skills.engine.md` Operation 6 for full details
284
+
285
+ The final agent context composition order is:
286
+ ```
287
+ Agent (.agent.md) → Crew Memory Rules → Platform Best Practices → Skill Index (Tier 1) → Skill Instructions (Tier 2, on-demand)
288
+ ```
289
+
290
+ 4. **Inject crew memory rules**: Before building the agent's execution prompt, inject accumulated correction rules from `crews/{name}/_memory/memories.md`:
291
+ a. Read `memories.md` and extract:
292
+ - `## Proibições Explícitas` — hard blocks, injected as NUNCA rules
293
+ - `## Regras de Ouro` — promoted patterns, injected as SEMPRE rules
294
+ - `## Estilo de Escrita` — writing style rules relevant to creator agents
295
+ - `## Design Visual` — visual rules relevant to designer agents
296
+ b. Build the injection block:
297
+ ```
298
+ --- CREW MEMORY (accumulated from past runs) ---
299
+
300
+ NUNCA:
301
+ {list of Proibições Explícitas, one per line}
302
+
303
+ SEMPRE:
304
+ {list of Regras de Ouro, one per line}
305
+
306
+ PREFERÊNCIAS:
307
+ {relevant rules from Estilo de Escrita and Design Visual for this agent}
308
+ ```
309
+ c. Inject this block immediately after the agent definition and BEFORE format/skill context.
310
+ d. Skip sections that are empty or not relevant to the current agent (e.g., skip Design Visual for a writer agent).
311
+ e. If `memories.md` has no accumulated rules → skip injection entirely (no empty block).
312
+
313
+ ### Context Compression (Summary-Based Handoff)
314
+
315
+ To prevent linear token growth across multi-agent pipelines, apply context compression
316
+ when passing prior agents' outputs as context:
317
+
318
+ 1. **TL;DR extraction**: After each agent completes, check if its output contains a `## TL;DR` section.
319
+ If present, extract and store it separately as the agent's summary.
320
+ ```bash
321
+ grep -q "^## TL;DR" "{outputFile}" && echo "HAS_TLDR" || echo "NO_TLDR"
322
+ ```
323
+
324
+ 2. **Compressed context assembly**: When preparing context for Agent N:
325
+ - Include **TL;DR summaries** from Agents 1 through N-2 (all agents except the direct predecessor)
326
+ - Include the **full output** from Agent N-1 (the direct predecessor) — this ensures
327
+ the current agent has complete detail from its immediate dependency
328
+ - Full outputs from all agents remain saved in `output/{run_id}/` for reference
329
+ - Skip any agent that was deselected for this run (`skipped_agents`) when walking
330
+ prior agents — its output file does not exist. Do not attempt to read it. The
331
+ "direct predecessor" is the previous agent in `filtered_steps` that actually ran.
332
+
333
+ 3. **Context format**:
334
+ ```
335
+ --- PRIOR CONTEXT (Summaries) ---
336
+
337
+ ### {Agent 1 Name} — Summary
338
+ {TL;DR content from Agent 1}
339
+
340
+ ### {Agent 2 Name} — Summary
341
+ {TL;DR content from Agent 2}
342
+
343
+ --- PREVIOUS STEP (Full Output) ---
344
+
345
+ {Complete output from Agent N-1}
346
+ ```
347
+
348
+ 4. **Fallback**: If an agent's output does NOT contain a `## TL;DR` section,
349
+ use the first 500 characters of the output as an auto-summary.
350
+ Going forward, the Architect should ensure all agent definitions include
351
+ a TL;DR requirement in their output instructions.
352
+
353
+ 5. **Single-agent crews**: If the pipeline has only 1 step, this rule does not apply.
354
+
355
+ 6. **Backward compatibility**: If the crew was created before this feature,
356
+ the runner falls back to passing full outputs (current behavior) when no
357
+ TL;DR sections are found in any prior output.
358
+
359
+ ### Task-Based Agent Execution
360
+
361
+ When an agent's `.agent.md` frontmatter contains a `tasks:` field:
362
+
363
+ 1. **Load task list**: Read the `tasks:` array from the agent's frontmatter
364
+ - Each entry is a relative path to a task file (e.g., `tasks/analyze-source.md`)
365
+ - Tasks execute in the order listed
366
+
367
+ 2. **For each task in sequence**:
368
+ a. Read the task file from the agent's directory (e.g., `crews/{crew-name}/agents/{agent}/tasks/{task}.md`)
369
+ b. Construct the execution prompt:
370
+ - Agent persona + principles (from agent.md — fixed across all tasks)
371
+ - Task description and process (from task file)
372
+ - Task output format (from task file)
373
+ - Task quality criteria and veto conditions (from task file)
374
+ - Input: For the first task, use the step's input. For subsequent tasks, use the previous task's output.
375
+ c. Execute the task (inline or subagent, matching the step's execution mode)
376
+ d. Collect the task output
377
+ e. Check task veto conditions (same enforcement as step veto conditions below)
378
+
379
+ 3. **Final output**: The output of the LAST task in the chain becomes the step's output
380
+ - Apply the Output Path Transformation (Steps 1 and 2: run_id injection + version folder) to the `outputFile` path before saving — this applies regardless of whether the step runs as `execution: inline` or `execution: subagent`
381
+ - Save to the **transformed** outputFile path
382
+ - This is what the next step (or checkpoint) receives
383
+
384
+ 4. **Progress reporting**: For inline execution, announce each task:
385
+ ```
386
+ {icon} {Agent Name} — Task {N}/{total}: {task name}...
387
+ ```
388
+
389
+ 5. **Backward compatibility**: If the agent's frontmatter does NOT contain a `tasks:` field,
390
+ execute the agent monolithically as before (current behavior unchanged).
391
+
392
+ ### Output Path Transformation
393
+
394
+ Before saving any output file in a step, apply these rules to determine the final path:
395
+
396
+ #### Step 1 — Insert run_id
397
+
398
+ - If the path starts with `crews/{name}/output/`, insert `{run_id}/` immediately after `output/`
399
+ - Example: `crews/carousel/output/slides/draft.md` → `crews/carousel/output/2026-03-03-143022/slides/draft.md`
400
+ - Example: `crews/carousel/output/angles-brief.yaml` → `crews/carousel/output/2026-03-03-143022/angles-brief.yaml`
401
+ - If the path does NOT start with `crews/{name}/output/`, leave it unchanged
402
+
403
+ #### Step 2 — Insert version folder
404
+
405
+ Apply to every path that was transformed in Step 1:
406
+
407
+ 1. Determine the **output group** = the parent directory of the file (after Step 1 transformation)
408
+ - Example: `crews/carousel/output/2026-03-03-143022/slides/draft.md` → group is `crews/carousel/output/2026-03-03-143022/slides/`
409
+ - Example: `crews/carousel/output/2026-03-03-143022/angles-brief.yaml` → group is `crews/carousel/output/2026-03-03-143022/`
410
+
411
+ 2. Detect existing versions for this group using Bash:
412
+ ```bash
413
+ ls -1 crews/{name}/output/{run_id}/{relative-group}/ 2>/dev/null | grep -E '^v[0-9]+$' | sort -V | tail -1
414
+ ```
415
+ - If the command returns a version (e.g. `v2`) → use `v3`
416
+ (Always increment the highest version found, even if lower versions have gaps — e.g. if `v1` and `v3` exist, use `v4`)
417
+ - If the command returns nothing (no versions yet) → use `v1`
418
+ (`{relative-group}` is the portion of the group path after `crews/{name}/output/{run_id}/`, e.g. `slides/` or empty string for root-level files)
419
+
420
+ 3. Insert the version folder immediately before the filename:
421
+ - `crews/carousel/output/2026-03-03-143022/slides/draft.md` → `crews/carousel/output/2026-03-03-143022/slides/v1/draft.md`
422
+ - `crews/carousel/output/2026-03-03-143022/angles-brief.yaml` → `crews/carousel/output/2026-03-03-143022/v1/angles-brief.yaml`
423
+
424
+ 4. **Cache per group**: within a single step execution, once a version is determined for a group, reuse it for all subsequent files in that same group. Do not re-run the `ls` per file.
425
+ If the same file path is written twice within a step, both writes go to the same versioned path (the second write overwrites the first within that version).
426
+
427
+ Apply this transformation consistently for every write in this step.
428
+
429
+ ### For each pipeline step:
430
+
431
+ 0. **Agent deselection check** — Read the step's `agent:` frontmatter field.
432
+ - If the step has an `agent:` value present AND it is in `skipped_agents` →
433
+ announce `⏭️ Skipping {Agent Name} (deselected for this run)` and skip this
434
+ step ENTIRELY: no dashboard update, no input validation, no execution, no output
435
+ validation, no veto, no output file, no handoff. Advance to the next step in
436
+ `filtered_steps`.
437
+ - Checkpoints that declare `agent:` and whose agent was deselected are skipped the
438
+ same way. Checkpoints with no `agent:` field always run (backward compatible).
439
+ - When the selection step was skipped (no `agent_dependencies:`), `skipped_agents`
440
+ is empty → this check never fires (legacy behavior).
441
+
442
+ 0b. **Update dashboard** (only if `dashboard_enabled`; otherwise skip to step 1). Write `crews/{name}/state.json` using the Write tool. Use this content:
443
+ ```json
444
+ {
445
+ "crew": "{crew code from crew.yaml}",
446
+ "status": "running",
447
+ "step": {
448
+ "current": {1-based index of this step},
449
+ "total": {total steps in pipeline},
450
+ "label": "{step id or label}"
451
+ },
452
+ "agents": [
453
+ {
454
+ "id": "{agent id}",
455
+ "name": "{agent displayName}",
456
+ "icon": "{agent icon}",
457
+ "status": "{working if this is the current step's agent, done if already completed, skipped if in skipped_agents, idle otherwise}",
458
+ "desk": {preserve existing desk positions from state.json — do not change col/row}
459
+ }
460
+ ],
461
+ "handoff": {preserve existing handoff object, or null if this is the first step},
462
+ "startedAt": "{ISO timestamp — set on the first step only, then preserve from existing state.json on subsequent steps}",
463
+ "updatedAt": "{ISO timestamp now}"
464
+ }
465
+ ```
466
+
467
+ 1. **Pre-Step Input Validation** — MANDATORY. If the step's frontmatter declares an `inputFile`, validate that the input exists before executing the step. Run via Bash tool:
468
+ ```bash
469
+ test -s "{transformed inputFile path}" && echo "VALIDATION:PASS" || echo "VALIDATION:FAIL"
470
+ ```
471
+ - Apply the Output Path Transformation (Step 1: run_id injection) to the `inputFile` path before running the check.
472
+ - If the Bash output contains `VALIDATION:PASS` → proceed to execute the step.
473
+ - If the Bash output contains `VALIDATION:FAIL` → do NOT execute the step. Present to user:
474
+ ```
475
+ ⚠️ Input for {Agent Name} not found: {path}
476
+ The previous step may have failed to produce output.
477
+
478
+ 1. Skip step and continue
479
+ 2. Abort pipeline
480
+ ```
481
+ Wait for user choice before proceeding. No retry — if the input doesn't exist, re-executing this step won't create it. The problem is upstream.
482
+ - If the step does not declare an `inputFile` → skip this validation entirely.
483
+ - Checkpoint steps (`type: checkpoint`) are exempt — they receive input from the user, not from files.
484
+
485
+ 2. **Read the step file** completely: `crews/{name}/pipeline/steps/{step-file}.md`
486
+ 3. **Check execution mode** from the step's frontmatter:
487
+
488
+ #### If `execution: subagent`
489
+ - Inform user: `🔍 {Agent Name} is working in the background...`
490
+ - Read the step's `model_tier` frontmatter field (if present).
491
+ Valid values: `fast` or `powerful`. If absent or any other value: default to `powerful`.
492
+ - **Before building the subagent prompt**: Apply the Output Path Transformation (Step 1: run_id injection + Step 2: version folder) to all output paths referenced in the step file. Store the transformed path(s) in working memory — they will be used both in the prompt and in post-completion verification. Never pass raw paths from the step file to the subagent.
493
+ - Use the Task tool to dispatch the step as a subagent:
494
+ - If `model_tier: fast`: use the fastest/lightest model available in your current IDE.
495
+ - If `model_tier: powerful` or absent/invalid: use the default model (no model override needed)
496
+ - In the Task prompt, include:
497
+ - The full agent persona from the party CSV
498
+ - The full agent `.agent.md` content (persona, principles, voice guidance, anti-patterns)
499
+ - If the agent has tasks: include ALL task files in order with instructions to execute sequentially, piping output from each task to the next
500
+ - If the agent has no tasks: include the step instructions and operational framework as before
501
+ - The veto conditions from the step file (agent should self-check before completing)
502
+ - The company context
503
+ - The crew memory
504
+ - The **transformed** path to save output (e.g., `crews/{name}/output/2026-03-20-140736/slides/v1/draft.md`)
505
+ - Wait for the subagent to complete
506
+ - Inform user: `✓ {Agent Name} completed`
507
+ - Proceed to Post-Step Output Validation (below) before advancing.
508
+
509
+ #### If `execution: inline`
510
+ - Switch to the agent's persona (read from party CSV)
511
+ - Announce: `{icon} {Agent Name} is working...`
512
+ - Follow the step instructions
513
+ - Present output directly in the conversation
514
+ - Save output to the specified output file — apply the Output Path Transformation (Steps 1 and 2) to the path before writing. Do not write to the raw path from the step file.
515
+ - Proceed to Post-Step Output Validation (below) before advancing.
516
+
517
+ #### If `type: checkpoint`
518
+ - Present the checkpoint message to the user
519
+ - If the checkpoint requires a choice (numbered list), present options as a numbered list
520
+ - **Always include the file path** of any generated content the user needs to review. Example: "Review the content at `crews/{name}/output/{run_id}/v1/content.md` and let me know if it looks good."
521
+ - Wait for user input before proceeding
522
+ - Save the user's choice/response for the next step
523
+ - **If the step frontmatter contains `outputFile`**: after collecting the user's full response,
524
+ apply the Output Path Transformation **Step 1 only** (run_id injection — skip Step 2, version folder) to the `outputFile` path, then write the response to the transformed path using the Write tool before moving to the next step. Checkpoint files are user input captures, not versioned output — Step 2 does not apply here, regardless of the general "every write" rule in the Output Path Transformation section above.
525
+ Use this format:
526
+ ```
527
+ # Research Focus
528
+
529
+ **Topic:** {user's typed topic}
530
+ **Time Range:** {selected time range label, e.g., "Últimos 7 dias"}
531
+ **Date:** {today's date in YYYY-MM-DD format}
532
+ ```
533
+ This file is the `inputFile` for the researcher step that follows.
534
+
535
+ ### Post-Step Output Validation
536
+
537
+ After a step produces output (subagent or inline) and BEFORE Veto Condition Enforcement, the runner MUST validate that the declared output files exist and are non-empty. This is a binary, non-negotiable gate — the runner does NOT proceed on memory or assumption, only on bash output.
538
+
539
+ **If the step declares an `outputFile`** (single or multiple), run via Bash tool for EACH output file:
540
+
541
+ ```bash
542
+ test -s "{transformed outputFile path}" && echo "VALIDATION:PASS" || echo "VALIDATION:FAIL"
543
+ ```
544
+
545
+ Use the **stored transformed path** (after Output Path Transformation Steps 1 and 2), not the raw path from the step file.
546
+
547
+ **Rules:**
548
+ - If ALL output files return `VALIDATION:PASS` → proceed to Veto Condition Enforcement.
549
+ - If ANY output file returns `VALIDATION:FAIL`:
550
+ 1. **Retry once**: re-execute the entire step with the same input and context.
551
+ 2. After re-execution, run the validation again for all output files.
552
+ 3. If second attempt returns `VALIDATION:PASS` for all files → proceed normally.
553
+ 4. If second attempt still has ANY `VALIDATION:FAIL` → present to user:
554
+ ```
555
+ ⚠️ {Agent Name}'s output was not generated: {path}
556
+
557
+ 1. Retry step
558
+ 2. Skip step and continue
559
+ 3. Abort pipeline
560
+ ```
561
+ Wait for user choice before proceeding.
562
+ - If the step does not declare an `outputFile` (e.g., steps that only produce inline console output) → skip output validation.
563
+ - Checkpoint steps (`type: checkpoint`) are exempt — their output is the user's response, not a file.
564
+
565
+ **IMPORTANT**: Do NOT rely on reading the file with the Read tool to "verify" output. The Read tool returns content that can be misinterpreted. Use ONLY the bash `test -s` command — its output is binary and cannot be hallucinated.
566
+
567
+ ### Output Contract Validation
568
+
569
+ If the step's frontmatter declares an `output_contract:` field, apply structured validation
570
+ AFTER the basic file existence check passes:
571
+
572
+ 1. **Required sections check**: If `output_contract.required_sections` is defined,
573
+ verify each required section exists in the output file:
574
+ ```bash
575
+ grep -c "^## " "{transformed outputFile path}" | xargs -I {} test {} -ge {min_sections} && echo "SECTIONS:PASS" || echo "SECTIONS:FAIL"
576
+ ```
577
+
578
+ 2. **TL;DR check**: If the output contract requires a TL;DR section:
579
+ ```bash
580
+ grep -q "^## TL;DR" "{transformed outputFile path}" && echo "TLDR:PASS" || echo "TLDR:FAIL"
581
+ ```
582
+
583
+ 3. **If any check fails**:
584
+ - Present to user: "⚠️ Output from {Agent Name} is incomplete: {which checks failed}"
585
+ - Options as numbered list:
586
+ 1. Accept anyway and continue
587
+ 2. Retry step (re-execute the agent)
588
+ 3. Abort pipeline
589
+
590
+ 4. **If no `output_contract` is defined**, skip this validation entirely (backward compatible).
591
+
592
+ Example `output_contract` in step frontmatter:
593
+ ```yaml
594
+ output_contract:
595
+ required_sections:
596
+ - "Fontes Pesquisadas"
597
+ - "Principais Descobertas"
598
+ - "TL;DR"
599
+ min_sections: 3
600
+ ```
601
+
602
+ ### Veto Condition Enforcement
603
+
604
+ After an agent completes a step (before moving to the next step):
605
+
606
+ 1. Check if the step file has a `## Veto Conditions` section
607
+ 2. If yes, evaluate each veto condition against the agent's output:
608
+ - Read the output that was just produced
609
+ - Check each condition (e.g., "slides exceed 30 words", "no CTA", "missing sources")
610
+ 3. If ANY veto condition is triggered:
611
+ - Inform user: "⚠️ {Agent Name}'s output triggered a veto: {condition}"
612
+ - Ask the agent to fix the specific issue (re-execute with targeted correction)
613
+ - Maximum 2 veto fix attempts per step
614
+ - After 2 failed attempts, present to user for manual decision
615
+ 4. If no veto conditions triggered: proceed to next step
616
+
617
+ This creates an internal quality loop BEFORE the reviewer sees the content,
618
+ catching obvious issues early and reducing review cycle waste.
619
+
620
+ ### Review Loops
621
+
622
+ When a step has `on_reject: {step-id}`:
623
+ - Track the review cycle count
624
+ - If reviewer rejects, go back to the referenced step
625
+ - Pass reviewer feedback to the writer agent
626
+ - If max_review_cycles reached, present to user for manual decision
627
+
628
+ ### Dashboard Handoff (between steps)
629
+
630
+ Only if `dashboard_enabled` (otherwise skip this entire section). After a step
631
+ completes output and there IS a next step:
632
+
633
+ 1. **Write delivering state** — Write `crews/{name}/state.json` with:
634
+ - Current step's agent: `"status": "delivering"`
635
+ - Next step's agent: `"status": "idle"`
636
+ - All other agents unchanged
637
+ - Pipeline `"status": "running"`
638
+ - Add or update `"handoff"`:
639
+ ```json
640
+ "handoff": {
641
+ "from": "{current agent id}",
642
+ "to": "{next agent id}",
643
+ "message": "{one-sentence summary of what was produced, written in the user's language}",
644
+ "completedAt": "{ISO timestamp now}"
645
+ }
646
+ ```
647
+ - `"updatedAt"`: now
648
+
649
+ 2. _(No delay — proceed immediately to working state)_
650
+
651
+ 2. **Write working state** — Write `crews/{name}/state.json` again with:
652
+ - Current agent: `"status": "done"`
653
+ - Next agent: `"status": "working"`
654
+ - Keep the `"handoff"` object from step 1 unchanged
655
+ - `"updatedAt"`: now
656
+
657
+ ### Step Execution Order (Summary)
658
+
659
+ For reference, the complete execution order for each pipeline step is:
660
+
661
+ ```
662
+ 0. Agent deselection check (skip step if its agent was deselected)
663
+ 0b. Dashboard update (state.json) — only if dashboard_enabled
664
+ 1. Pre-Step Input Validation (bash gate)
665
+ 2. Read step file
666
+ 3. Check execution mode and execute (subagent / inline / checkpoint)
667
+ 4. Post-Step Output Validation (bash gate)
668
+ 5. Veto Condition Enforcement
669
+ 6. Dashboard Handoff (to next step) — only if dashboard_enabled
670
+ ```
671
+
672
+ Steps 1 and 4 are binary bash gates. If either fails, the pipeline does NOT advance — the user is consulted.
673
+
674
+ ### After Pipeline Completion
675
+
676
+ 1. Save final output to `crews/{name}/output/{run_id}/{filename}.md`
677
+ (The run folder was created during initialization — no separate date subfolder needed)
678
+ 1b. **Update dashboard** (only if `dashboard_enabled`; otherwise skip to step 2 below). Write `crews/{name}/state.json` with:
679
+ - `"status": "completed"`
680
+ - All agents: `"status": "done"`
681
+ - `"updatedAt"`: now
682
+ - `"completedAt"`: now
683
+ - `"startedAt"`: preserve from existing `state.json`
684
+ - Keep existing `"handoff"` object
685
+
686
+ ### Post-Completion Cleanup (only if `dashboard_enabled`)
687
+
688
+ After writing the final "completed" state to `crews/{name}/state.json`:
689
+
690
+ 1. Add the `completedAt` field (or `failedAt` if status is `failed`) with the current ISO timestamp
691
+ 2. Copy `state.json` to the run output folder for permanent history:
692
+ ```bash
693
+ cp crews/{name}/state.json crews/{name}/output/{run_id}/state.json
694
+ ```
695
+ 3. Leave the working copy of `crews/{name}/state.json` in place — do not delete it and
696
+ do not add an artificial delay. A dashboard watching the file already sees the
697
+ "completed" status the moment it's written; the next run's initialization (step 6)
698
+ overwrites this file from scratch. There is nothing to clean up.
699
+
700
+ This archives the run state for the `runs` command while keeping crew history available.
701
+
702
+ 2. **Update crew memory** — write to BOTH files (runs after Post-Completion Cleanup above):
703
+
704
+ ### 2a. Update `memories.md` (living preferences)
705
+
706
+ Read `crews/{name}/_memory/memories.md` in full. Then identify candidates from this run: **only explicit user feedback** — approvals with comments, rejections with reasons, direct requests ("prefiro X", "não quero Y"). Never infer preferences.
707
+
708
+ For each candidate:
709
+ - If an equivalent memory already exists and is compatible → skip (no duplicate)
710
+ - If an equivalent memory exists but contradicts the new item → replace with the newer version
711
+ - If no equivalent exists → add to the correct semantic section:
712
+ - Writing style choices → `## Estilo de Escrita`
713
+ - Visual/design preferences → `## Design Visual`
714
+ - Content structure choices → `## Estrutura de Conteúdo`
715
+ - Explicit rejections or prohibitions → `## Proibições Explícitas`
716
+ - Crew-specific technical patterns → `## Técnico (específico do crew)`
717
+
718
+ **Never write to `memories.md`:**
719
+ - Runner inferences ("usuário parece preferir X")
720
+ - Run scores, review grades, output file paths, topics from past runs
721
+
722
+ **Technical routing:** For any technical learning (bugs, workarounds, API behavior):
723
+ - If it affects any crew (Playwright bugs, OS rendering quirks, API limits) → write to the appropriate `_opencrew/core/best-practices/` file instead of `memories.md`
724
+ - If it is specific to this crew's output type or toolchain → add to `## Técnico (específico do crew)` following the dedup rules above
725
+
726
+ After applying all candidates, write the updated `memories.md`.
727
+
728
+ If no candidates are found (the run had no explicit user feedback), skip writing `memories.md` entirely — do not write an unmodified copy. Always proceed to step 2b regardless.
729
+
730
+ ### 2b. Prepend to `runs.md` (reverse-chronological log — newest run first)
731
+
732
+ If `crews/{name}/_memory/runs.md` does not exist, create it first with:
733
+ ```markdown
734
+ # Run History: {crew-name}
735
+
736
+ | Data | Run ID | Tema | Output | Score | Resultado |
737
+ |------|--------|------|--------|-------|-----------|
738
+ ```
739
+ Then proceed to prepend the new row.
740
+
741
+ Read `crews/{name}/_memory/runs.md`. Prepend one new row to the table (immediately after the header row), with:
742
+ - `Data`: today's date in YYYY-MM-DD format
743
+ - `Run ID`: the `run_id` for this execution
744
+ - `Tema`: the topic or user request from this run (1 sentence max)
745
+ - `Output`: brief description of what was generated (e.g., "Carrossel 9 slides", "Thread 7 posts")
746
+ - `Score`: `{approved}/{total}` agent outputs approved without corrections (e.g., `4/5`)
747
+ - `Resultado`: one of — `Aprovado` / `Rejeitado` / `Publicado` / `Abortado`
748
+
749
+ No other data.
750
+
751
+ The `Score` column tracks how many agent outputs were approved by the user without corrections in this run. Count only explicit checkpoint approvals (not "skip" or "continue"). Format: `{approved}/{total checkpoints}` (e.g., `4/5` means 4 of 5 agent outputs were approved as-is).
752
+
753
+ ### 2c. Post-Run Reflection (pattern detection)
754
+
755
+ After updating `memories.md` and `runs.md`, run a reflection pass. This is a lightweight analysis — not a full agent execution, just pattern matching on the run's feedback and past memory.
756
+
757
+ 1. **Collect this run's corrections**: From checkpoint responses, gather every user rejection or correction. A correction is:
758
+ - A rejected output with a reason ("tom muito informal", "cor não combina", "fonte sem data")
759
+ - A modification request during checkpoint ("muda o título para X", "usa azul em vez de verde")
760
+
761
+ 2. **Look for recurrence**: Compare each correction against past runs recorded in `memories.md`:
762
+ - Search `memories.md` for similar patterns (same category, same agent, same type of correction)
763
+ - Count: how many past runs have a correction matching this pattern?
764
+ - A "match" means the same agent + same type of error (e.g., "redator + tom informal", "designer + cores saturadas")
765
+
766
+ 3. **Promote to Regra de Ouro**: If the SAME pattern appears in **3 or more runs** (including this one):
767
+ a. Add a new entry under `## Regras de Ouro` in `memories.md`:
768
+ ```markdown
769
+ ## Regras de Ouro (promovidas após 3+ ocorrências)
770
+
771
+ - **{Agent role}**: SEMPRE {correct behavior}. {Why — grounded in user feedback}.
772
+ (Runs: #{run1}, #{run2}, #{run3})
773
+ ```
774
+ Example:
775
+ ```markdown
776
+ - **Redator**: SEMPRE verificar se o CTA contém link rastreável antes de finalizar.
777
+ (Runs: #2026-08-01-143022, #2026-08-05-091530, #2026-08-10-160845)
778
+ ```
779
+ b. Remove the individual entries from their original sections (`## Estilo de Escrita`, `## Design Visual`, etc.) — the Regra de Ouro replaces them.
780
+ c. Display to the user:
781
+ ```
782
+ 💡 Regra de Ouro detectada:
783
+ "{correct behavior}" aconteceu 3 vezes.
784
+ Vou aplicar automaticamente a partir de agora.
785
+ ```
786
+
787
+ 4. **Mark improvement**: If a previously recurring error did NOT happen this run:
788
+ - Add a `✅` marker to the Regra de Ouro entry: `✅ **Redator**: SEMPRE ...`
789
+ - This tracks that the crew is improving — the rule is working.
790
+
791
+ 5. **Bail out early**: If this run had zero corrections (all checkpoints approved), skip the entire reflection — nothing to learn.
792
+
793
+ 6. **Reflection budget**: Maximum 30 seconds of analysis. If the crew has a long history (>20 past runs), sample the most recent 10 runs for pattern matching. This is a quick scan, not an exhaustive audit.
794
+
795
+ 3. Present completion summary:
796
+ ```
797
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
798
+ ✅ Pipeline complete!
799
+ 📁 Run folder: crews/{name}/output/{run_id}/
800
+ 📄 Output saved to: {output path}
801
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
802
+
803
+ What would you like to do?
804
+ ● Run again (new topic)
805
+ ○ Edit this content
806
+ ○ Back to menu
807
+ ```
808
+
809
+ ## Error Handling
810
+
811
+ - If a subagent fails, retry once. If it fails again, inform the user and offer to skip the step or abort.
812
+ - If a step file is missing, inform the user and suggest running `/opencrew edit {crew}` to fix.
813
+ - If company.md is empty, stop and redirect to onboarding.
814
+ - Never continue past a checkpoint without user input.
815
+
816
+ ## Pipeline State
817
+
818
+ Track pipeline state in memory during execution:
819
+ - Run ID (run_id) — the output subfolder name for this execution
820
+ - Current step index
821
+ - Outputs from each completed step (file paths)
822
+ - User choices at checkpoints
823
+ - Review cycle count
824
+ - Start time
825
+ - selected_agents / skipped_agents — the agent sets from Pre-Execution Agent Selection (step 4b)
826
+ - filtered_steps — the ordered steps that will actually run this execution
827
+ - missing_dependency — true if the user knowingly ran with a broken dependency
828
+
829
+ This state does NOT persist to disk — it exists only during the current run.