# Research: Optimal Context for Placement Agent Prompts

**Task:** research-placement-context  
**Date:** 2026-03-19  
**Status:** Complete

---

## 1. Current Placement Prompt Template

The placement prompt is generated by `build_placement_context()` in `src/commands/eval_scaffold.rs:80-126`. It was significantly trimmed in commit `2c7a22d` (2026-03-19) to prevent scope creep.

**Current template (verbatim from source):**

```
## Task to place
ID: {task.id}
Title: {task.title}
Existing deps: {task.after.join(", ")}    // only if non-empty

## Active tasks (non-terminal)
- {task.id} ({task.title})
- ...

## Your job
Decide where task '{task_id}' belongs in the dependency graph.
Do NOT modify .assign-*, .flip-*, .evaluate-*, or any other dot-task.

## Output format (CRITICAL)
You MUST output EXACTLY one line as the LAST LINE of your response:
- A `wg edit` command to add edges: `wg edit {task_id} --after <dep-id>` (or `--before <dep-id>`, or both)
- OR the word `no-op` if no placement changes are needed

You may reason about the placement above the last line, but the LAST LINE
must be the command or `no-op`. Do NOT run any commands yourself.
```

The task description becomes the `.place-*` task's `description` field. At execution time (`src/commands/spawn/execution.rs:629-680`), bare-mode tasks get `--max-turns 1` and no tool access. The user message piped to the LLM is:

```
Complete this task:

Title: {task_id}

{task_description}
```

## 2. What Context Is Currently Injected

After the March 19 trim, the context is **intentionally minimal**:

| Element | Included | Format |
|---------|----------|--------|
| Task ID | ✓ | Plain text |
| Task title | ✓ | Plain text |
| Task description/summary | ✗ (removed in 2c7a22d) | — |
| Existing deps (after) | ✓ (if non-empty) | Comma-separated IDs |
| Files mentioned | ✗ (removed) | — |
| Placement hints (place_near, place_before) | ✗ (removed) | — |
| Active task IDs + titles | ✓ | `- id (title)` list |
| Active task descriptions | ✗ | — |
| Active task deps/edges | ✗ | — |
| Active task tags | ✗ | — |
| Active task artifacts | ✗ (removed) | — |
| Recently completed tasks | ✗ (removed) | — |
| Integration gates | ✗ (removed) | — |

**Prior to the trim**, the prompt also included:
- First-line summary of task description (max 150 chars)
- File paths extracted from description
- Placement hints (place_near, place_before)
- Active task status and artifact file lists

**Even earlier** (coordinator-generated placement), the prompt included the full task description, recently completed tasks with artifacts, integration gates, and 5-step instructions.

## 3. What Would an Ideal Placement Prompt Contain

The placement agent's job is **graph topology only**: decide which existing tasks this new task should depend on (--after) or block (--before). To do this well, it needs to understand:

### Must have (currently missing)
1. **Dependency edges between active tasks** — Without seeing the graph structure, the agent can't reason about where a task fits in a pipeline. It can only match titles.
2. **Brief task summaries** — Title alone is often ambiguous. A one-line summary (first sentence or first 80 chars) disambiguates without causing scope creep.
3. **Placement hints** — `place_near` and `place_before` were removed but are explicitly supported by the CLI (`--place-near`, `--place-before`). These should be injected.
4. **Tags** — Tags like `evaluation`, `agency`, `flip` help the agent understand task categories and avoid cross-cutting edges.

### Should have
5. **Recently completed tasks (last 5-10)** — Provides temporal context about what just finished. Helps place tasks that logically follow recent work.
6. **Files mentioned in description** — The strongest signal for dependency. If task A modifies `coordinator.rs` and task B also modifies it, they must be serialized.

### Should NOT have
- **Full task descriptions** — Causes scope creep (agent tries to solve the problem). Confirmed by commit 2c7a22d experience.
- **Implementation details, code snippets, validation criteria** — Not relevant to topology.
- **Logs, token usage, agent assignments** — Noise.

## 4. Token Budget Estimate

Based on analysis of 329 non-system tasks in this project (avg ID: 20 chars, avg title: 53 chars, avg 0.7 non-system deps):

| Format | 25 tasks | 50 tasks | 75 tasks | 100 tasks |
|--------|----------|----------|----------|-----------|
| Slim (ID+title) | ~544 tok | ~1,038 tok | ~1,532 tok | ~2,027 tok |
| With deps | ~674 tok | ~1,299 tok | ~1,923 tok | ~2,547 tok |
| Rich (deps+summary+tags) | ~1,024 tok | ~1,765 tok | ~2,507 tok | ~3,248 tok |

**Add ~500 tokens for prompt overhead** (instructions, output format, task-to-place section).

**Verdict: Trivially feasible for haiku** (200k context window). Even the richest format at 100 active tasks is under 4k tokens total. There is no need to cap or summarize. The constraint is quality, not size.

Actual token usage across 122 completed placement tasks: avg 21k input tokens (dominated by system prompt overhead from Claude Code, not the placement context itself), avg 2.9k output tokens. Average cost: $0.03/placement.

## 5. Recommended Format

### Adjacency-list format with summaries

This format gives the agent the graph structure compactly:

```
## Task to place
ID: fix-coordinator-crash
Title: Fix coordinator crash on empty graph
Summary: Coordinator panics when graph.jsonl is empty (zero tasks)
Files: src/commands/service/coordinator.rs
Existing deps: (none)
Hints: near=fix-coordinator-task-connectivity

## Graph (non-terminal tasks)
ID                              | Title                                    | After              | Tags
fix-viz-sorting                 | Fix viz ASCII sorting                    |                    |
audit-integrate                 | Integrate audit findings                 | audit-a,audit-b    | integration
wire-compacted-context          | Wire compacted context into coordinator  | research-compaction |
implement-wg-sweep              | Implement wg sweep command               |                    |

## Recently completed (last 5)
ID                              | Title                                    | Artifacts
fix-tui-editing                 | Fix TUI editing mode                     | src/tui/viz_viewer/state.rs
implement-agency-pipeline       | Implement agency pipeline                | src/commands/service/coordinator.rs

## Instructions
Decide where 'fix-coordinator-crash' belongs in the dependency graph.
- Add --after edges for tasks that MUST complete before this task starts
- Add --before edges for tasks that should wait for this task
- Key signal: tasks modifying the SAME FILES should be serialized
- Do NOT modify .assign-*, .flip-*, .evaluate-*, or any dot-task

## Output (CRITICAL)
LAST LINE must be exactly one of:
- `wg edit fix-coordinator-crash --after <dep> --before <dep>`
- `no-op`
```

### Why this format

1. **Table format** — Compact, scannable, familiar to LLMs. Better than indented-dep or adjacency-list formats for quick visual parsing.
2. **Summary field** — One-line summary avoids the scope creep problem while providing disambiguation. Truncate at ~80 chars.
3. **Files column omitted from graph table** — Files are extracted separately for the task-to-place section. Including artifacts for every task would bloat the prompt without proportional benefit. Recently-completed artifacts are sufficient for file-overlap detection.
4. **Placement hints restored** — These are user-provided signals. Removing them discards intentional input.
5. **After column in table** — The key missing piece. Without this, the agent has no way to understand pipeline structure.
6. **Tags column** — Helps identify task categories (integration gates, etc.).

## 6. Analysis: Successful vs Failed Placements

### Quantitative results (123 completed .place-* tasks)

| Outcome | Count | % |
|---------|-------|---|
| Edges added (successful placement) | 70 | 57% |
| No-op (no edges added) | 53 | 43% |
| Failed | 0 | 0% |
| Needed retries (agent died mid-output) | 33 | 27% |

### Successful placements (edges added)

**`.place-impl-evolver-analyzers`** — Rich context (pre-trim). Added `after=impl-evolver-partition,create-evolver-skills` and `before=impl-evolver-synthesize`. This was a sophisticated placement requiring understanding of a multi-step pipeline. The agent had full descriptions and artifact lists.

**`.place-audit-tui-disable-fade`** — Added `before=audit-integrate`. The agent recognized the integration-gate pattern from the context listing `audit-integrate` with 12 deps.

**`.place-push-and-verify-ci`** — Added `after=validate-build,sweep-orphaned-deps`. Agent identified prerequisite tasks correctly.

### No-op placements

**`.place-fix-agency-pipeline`** — No edges added. This was one of the first tasks in its area, with no clear dependencies. No-op was likely correct.

**`.place-message-status-colors`** — No edges. A standalone UI task with no dependencies — no-op is arguably correct.

**`.place-publish-creates-full`** — 4 retries, ultimately no edges. This task had complex interactions but the agent couldn't identify them from title alone.

### What would have helped

1. **Dependency edges in context** — The most successful placements were from the rich-context era when the agent could see the graph structure. Tasks like `impl-evolver-analyzers` required understanding the pipeline shape to place correctly.

2. **File-overlap detection** — Tasks mentioning the same files should be serialized. The old format included artifact file lists; the current format has nothing. This is the strongest mechanical signal for placement.

3. **Recently completed tasks** — Provides temporal ordering context. New tasks often logically follow recent completions.

4. **Retry pattern** — 27% of placements needed retries because agents died before producing structured output. This is an execution reliability issue, not a context issue. The `--max-turns 1` + bare mode fixes this going forward.

## Artifacts Summary

- **Current placement prompt template**: `src/commands/eval_scaffold.rs:80-126` (`build_placement_context`)
- **Placement output parsing**: `src/commands/placement.rs` (`parse_placement_command`, `apply_placement_command`)
- **Execution path**: `src/commands/spawn/execution.rs:629-680` (bare mode, `--max-turns 1` for `.place-*`)
- **Wrapper script**: `src/commands/spawn/execution.rs:849-866` (`wg apply-placement` post-processing)
- **Failed-placement fallback**: `src/commands/service/coordinator.rs:752-801` (`build_placement_tasks`)
- **Graph struct**: `src/graph.rs:195-363` (Task fields including `place_near`, `place_before`)

## Recommendation

**Enrich the current slim context with three additions:**

1. **Restore `After` column** — Show non-system dependency edges for each active task. This is the single most impactful change: it lets the agent reason about graph topology instead of guessing from titles.

2. **Add one-line summaries** — First 80 chars of description for the task-to-place, and titles (already present) for the graph table. Do NOT include full descriptions.

3. **Restore placement hints** — `place_near` and `place_before` are user-provided signals that should be surfaced.

**Optional but valuable:**
- Recently completed tasks (last 5) with artifact file lists — enables file-overlap detection
- Tags column for active tasks — helps identify integration gates and task categories

**Do NOT restore:**
- Full task descriptions (confirmed scope-creep problem)
- Multi-step instructions (the structured-output format is sufficient)
- Integration gates section (redundant with showing deps — integration tasks naturally appear as highly-connected nodes)

**Token budget:** Even at 100 active tasks with the richest format, total prompt is under 4k tokens. No caps or summarization needed for haiku's 200k window.
