desktop-control-trajectory-generation · git:20260826.8da8b03 · 2026-08-26 · sha256 9a9dd80d8169c128
desktop-control-trajectory-generation git:20260826.8da8b03C
Immutable. This exact content is served forever at /api/v1/blob/9a9dd80d8169c128.
# Skill: desktop-control-trajectory-generation
# Desktop-Control Training Corpus Generation (Phase C of the Desktop-Agent Program)
## Problem It Solves
UI-TARS's hardest-won lesson applies to us: procedural action-only data produces
surface mimicry without internalized logic. This skill defines how we generate,
verify, gate, and version training trajectories for the desktop-control model —
every row carrying explicit reasoning, every row execution-verified (R3).
## Research Foundations
| Source | Fact | Rule here |
|---|---|---|
| UI-TARS 2 data flywheel | CT→SFT→RL stages; verifier V(s) routes rollouts: V=1 → SFT pool, V=0 → lower-stage pool | Same routing: PASS → sft pool, FAIL → reflection/DPO pool, never discarded silently |
| UI-TARS 1 | Reflection tuning on failure-recovery traces beats clean-only data | ~15% of rows must be recovery traces: mistake → observed consequence → corrected action |
| UI-TARS DPO | Preference pairs from same-task correct vs incorrect actions beat generic pairs | DPO pairs are SAME snapshot + different action + verified outcome delta |
| zero-dup-high-quality law (house) | No duplicate/near-dup docs; highest quality or nothing | Jaccard dedup on observation+action sequence; seed-driven diversity |
| anti-trash-data-doctrine | Generated data passes identical gates as scraped data | Verifier stamp or the row does not exist |
| trio dataset laws (aide-trio-tuning) | Assistant-only masking; structured truncation; phase gates | Same collation rules; observations are masked context, actions+thoughts are targets |
## Corpus Composition Targets (v0)
| Slice | Share | Source |
|---|---|---|
| Clean task trajectories (Thought+Action per turn to finished()) | ~55% | seeded sandbox rollouts, verifier-PASS |
| Recovery/reflection trajectories | ~15% | injected faults: wrong window focused, element disabled, typo'd value |
| Refusal-recovery (FORBIDDEN class → call_user/alternative) | ~10% | probe actions against gated targets |
| Permission-gate interactions (approve flows rendered honestly) | ~10% | WRITE/OPEN tasks incl. PENDING_APPROVAL turns |
| Idle/honest-failure endings (call_user when stuck) | ~10% | intentionally unsolvable variants |
Scale target for v0 gate: ≥800 verified multi-turn tasks (~15–25k turns), matching
trio-program scale that already proved itself on this card.
## Seed Task Design (the diversity engine)
Seeds live in `desktop_seeds/*.json`: {task, app_scope, steps_hint, assertions[],
difficulty 1-5, category}. Categories v0:
file_ops(notepad/explorer), settings_flows(calculator/browser), form_filling,
app_launch_and_navigate, cross_app_copy, browser_activated_flows.
Diversity laws:
- Evolve don't copy: each batch mutates app order, values, window counts, error
injection points; no two seeds share >0.85 Jaccard on step skeleton
- Values randomized (names, amounts, paths from a fixture bank) so the model learns
process, not strings
- Every seed lists its ASSERTIONS up front — written BEFORE rollout, not after
## Rollout Protocol
```
for seed in seeds:
session = executor.new_session(scope=seed.app_scope)
traj = record(seed, policy=current_model_or_scripted_teacher)
verdict = assertions.check(traj.final_state) # V(s)
if verdict == PASS -> sft_pool(traj)
elif fault_was_injected -> recovery_pool(traj) # only intentional faults
else -> dpo_candidates(traj) # pair w/ a passing variant
audit_log.rotate(session_end=True)
```
Two generator modes:
1. **Scripted teacher** (deterministic pywinauto scripts per seed family): writes
gold Thought lines from templates + real snapshots. Cheap, reliable, boring —
the backbone of v0.
2. **Model rollouts** (current checkpoint): rejection-sampled; only verifier-PASS
rollouts enter SFT; failures feed DPO/reflection pools. Never self-training on
unverified output (R3/STaR lesson).
## Row Format (chat template of the trio program)
system: harness scaffold (desktop tier: action-space cheat sheet + refusal law +
scope statement). Each user turn: TASK + latest numbered snapshot. Assistant turn:
`Thought: ...\nAction: ...`. Observation spans are MASKED from loss (context only);
Thought+Action lines carry loss. Final assistant turn ends with `finished(summary)`
or `call_user(reason)`.
## What NOT To Do
1. NO training rows from unverified sessions (no assertion stamp = no row).
2. NO synthetic/fabricated snapshots — snapshots come from REAL UIA renders during
rollouts (OS-Atlas lesson: grounding data must match reality).
3. NO password fields, personal files, or real user data in any scope — fixtures
only (E:\desktop_sandbox\fixtures).
4. NO near-dup inflation: dedup before staging (Jaccard >0.85 on step skeleton);
report collision counts per batch.
5. NO silent schema drift: row validator checks DSL grammar against spec v1;
rejects unknown verbs/fields loudly.
## Dependencies
- windows-desktop-sandbox-harness (executor + AssertionEngine + audit log)
- aide-desktop-agent-model-spec (DSL v1 grammar — validator generated from it)
- pilot_qlora.py recipe (consumption side), trajectory-recorder spec (record shape)
- Fixture bank under E:\desktop_sandbox\fixtures (created by this phase)
## Verification Gates (before Phase D fine-tune may start)
- [ ] ≥800 staged rows, all with PASS/recovery stamps + audit-log sha linkage
- [ ] Dedup report: 0 collisions >0.85; category coverage within ±10pp of targets
- [ ] Format validator: 100% of staged rows parse; DSL grammar violations = 0
- [ ] Held-out 40-seed eval set locked (hash-listed) BEFORE training starts
- [ ] Human spot-check: 20 random rows reviewed for Thought quality (not filler)