Skill Tracer
Skills › Compound Engineering › ce-retune › baseline-mining.md

baseline-mining.md

122 lines · skills/ce-retune/references/baseline-mining.md at 3449230

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Phase 1: mine the archive
2
3Zero model cost. Everything here reads files that already exist on disk. Do not run the harness in this phase. Phase 2 is where the first paid runs happen (`references/noise-floor.md`).
4
5An archive is usually an order of magnitude larger than the experiment you can afford this week. In the engagement this method came from, 745 archived runs were on disk and 458 carried usable traces. That is more evidence than any deliberate sample, sitting unread.
6

Phase 1: mine the archive

Zero model cost. Everything here reads files that already exist on disk. Do not run the harness in this phase. Phase 2 is where the first paid runs happen (references/noise-floor.md).

An archive is usually an order of magnitude larger than the experiment you can afford this week. In the engagement this method came from, 745 archived runs were on disk and 458 carried usable traces. That is more evidence than any deliberate sample, sitting unread.

Raw lines 1 to 6
7## What the archive must contain
8
9Per run, in whatever form the harness stores it (JSONL transcript, structured log, a directory per run): the ordered tool-call trace, token counts, timestamps, and the final assistant message. If it stores only a pass/fail verdict, the archive is not minable. Say so and go to Phase 2.
11Find the archive by asking the harness where it writes run output, or by locating the directory it appends to after a run. Do not assume a schema. Read one run end to end and derive the field paths before writing any extractor.

What the archive must contain

Per run, in whatever form the harness stores it (JSONL transcript, structured log, a directory per run): the ordered tool-call trace, token counts, timestamps, and the final assistant message. If it stores only a pass/fail verdict, the archive is not minable. Say so and go to Phase 2.

Find the archive by asking the harness where it writes run output, or by locating the directory it appends to after a run. Do not assume a schema. Read one run end to end and derive the field paths before writing any extractor.

Raw lines 7 to 12
13## Build the phase-marker map first
15`phase_trace`, `process_followed`, and the terminal-phase cross-tab are all functions of one artifact that does not exist yet: a table mapping each phase of the corpus's own workflow to the observable side effect that proves it ran. Derive it before writing the extractor, by reading the corpus's spine. Do not infer phases from the logs; that is circular.
17| Phase name, in spine order | Marker in the trace |
18|---|---|
19| `<phase>` | the reference file it must read, the helper it must dispatch, the artifact path it must write, or the sentinel it must emit |
21Rules: one marker per phase minimum, each a **tool call or a file that exists**, never a phrase in the assistant's prose. A phase with no observable marker cannot be scored. Record it as unobservable rather than assuming it ran, and carry that list forward. It is the same list Phase 2 needs for the probe's unentered phases and Phase 5 needs for the unmeasured paths. Keep the map in the same directory as the extractor. Every later re-run and every re-scored table depends on it.

Build the phase-marker map first

phase_trace, process_followed, and the terminal-phase cross-tab are all functions of one artifact that does not exist yet: a table mapping each phase of the corpus's own workflow to the observable side effect that proves it ran. Derive it before writing the extractor, by reading the corpus's spine. Do not infer phases from the logs; that is circular.

Phase name, in spine orderMarker in the trace
<phase>the reference file it must read, the helper it must dispatch, the artifact path it must write, or the sentinel it must emit

Rules: one marker per phase minimum, each a tool call or a file that exists, never a phrase in the assistant's prose. A phase with no observable marker cannot be scored. Record it as unobservable rather than assuming it ran, and carry that list forward. It is the same list Phase 2 needs for the probe's unentered phases and Phase 5 needs for the unmeasured paths. Keep the map in the same directory as the extractor. Every later re-run and every re-scored table depends on it.

Raw lines 13 to 22
Starts an agent dispatch :19
23## Extract one row per run
25Write a script, not a per-run read. Reading 458 transcripts by hand is the failure mode this phase is supposed to avoid.
27| Field | How to derive it | Why it pays for itself |
28|---|---|---|
29| `run_id`, `model`, `settings` | harness metadata | the stratification keys; without them the whole table is one undifferentiated blob |
30| `session_id`, and the child id on every dispatch | whatever the trace calls the conversation and the spawned agent | the only way to tell a real runtime boundary from a fictional one. `references/halt-taxonomy.md` opens on this comparison; extract it here or that diagnostic has no data |
31| `phase_trace` | ordered list of which corpus phases ran | tells you **where** it stopped, not just that it did. This is the field that localizes the defect |
32| `marker_present` | boolean; the corpus's own terminal marker in the final message | the corpus's own claim of completion, separable from whether it is true |
33| `output_tokens` | harness token accounting | the variance channel; spread here is a stronger signal than the mean |
34| `wall_clock_min` | last timestamp minus first | useless alone, required as a denominator |
35| `helper_dispatches` | count of subagent/helper dispatches | how far the run got, and how it got there |
36| `max_parallel_dispatch` | most dispatched in a single message | separates fan-out from serial plodding; a corpus that mandates parallelism and never gets it is a finding |
37| `final_message` | verbatim, untruncated | halt language lives here and nowhere else. Do not summarize it during extraction |
39Derive `phase_trace` from **artifacts, not claims**. A phase ran if the trace shows its side effect: the reference file it must read, the helper it must dispatch, the file it must write. A run asserting "Phase 3 complete" in prose is not evidence. The defect class you are hunting is exactly runs that report success without doing the work.

Extract one row per run

Write a script, not a per-run read. Reading 458 transcripts by hand is the failure mode this phase is supposed to avoid.

FieldHow to derive itWhy it pays for itself
run_id, model, settingsharness metadatathe stratification keys; without them the whole table is one undifferentiated blob
session_id, and the child id on every dispatchwhatever the trace calls the conversation and the spawned agentthe only way to tell a real runtime boundary from a fictional one. references/halt-taxonomy.md opens on this comparison; extract it here or that diagnostic has no data
phase_traceordered list of which corpus phases rantells you where it stopped, not just that it did. This is the field that localizes the defect
marker_presentboolean; the corpus's own terminal marker in the final messagethe corpus's own claim of completion, separable from whether it is true
output_tokensharness token accountingthe variance channel; spread here is a stronger signal than the mean
wall_clock_minlast timestamp minus firstuseless alone, required as a denominator
helper_dispatchescount of subagent/helper dispatcheshow far the run got, and how it got there
max_parallel_dispatchmost dispatched in a single messageseparates fan-out from serial plodding; a corpus that mandates parallelism and never gets it is a finding
final_messageverbatim, untruncatedhalt language lives here and nowhere else. Do not summarize it during extraction

Derive phase_trace from artifacts, not claims. A phase ran if the trace shows its side effect: the reference file it must read, the helper it must dispatch, the file it must write. A run asserting "Phase 3 complete" in prose is not evidence. The defect class you are hunting is exactly runs that report success without doing the work.

Raw lines 23 to 40
Starts an agent dispatch :30
Starts an agent spawned :30
Starts an agent subagent :35
Starts an agent dispatches :35
Starts an agent dispatched :36
41## Derived metrics
43**Tokens per minute is the metric that separates working from stalling.** `output_tokens / wall_clock_min`. Compute it for every run and look for bimodality before looking at anything else.
45In the engagement, healthy cells ran 10-12k tokens/min; every failing cell sat at 1.5-3.8k. A run burning hours at 2k tok/min is not thinking hard. It is waiting, because the prose told it a second party would respond. Duration alone cannot show this. A long successful run and a long stalled run look identical until you divide.
47Treat those bands as the shape to look for, not as thresholds to import. Find your own corpus's two clusters, then read the gap.
49**The two booleans the spine requires, derived independently:**
51```
52task_done = the run's expected deliverable exists (artifact on disk, commit, PR, file changed)
53process_followed = every required phase appears in phase_trace, in spine order
54```
56Never let one imply the other, and never let `marker_present` stand in for either. `task_done AND NOT process_followed` is `done-no-workflow` below: the run did the job inline and skipped the corpus. Collapsed into one success column, it reads as a win and hides the most expensive defect in the set.

Derived metrics

Tokens per minute is the metric that separates working from stalling. output_tokens / wall_clock_min. Compute it for every run and look for bimodality before looking at anything else.

In the engagement, healthy cells ran 10-12k tokens/min; every failing cell sat at 1.5-3.8k. A run burning hours at 2k tok/min is not thinking hard. It is waiting, because the prose told it a second party would respond. Duration alone cannot show this. A long successful run and a long stalled run look identical until you divide.

Treat those bands as the shape to look for, not as thresholds to import. Find your own corpus's two clusters, then read the gap.

The two booleans the spine requires, derived independently:

task_done       = the run's expected deliverable exists (artifact on disk, commit, PR, file changed)
process_followed = every required phase appears in phase_trace, in spine order

Never let one imply the other, and never let marker_present stand in for either. task_done AND NOT process_followed is done-no-workflow below: the run did the job inline and skipped the corpus. Collapsed into one success column, it reads as a win and hides the most expensive defect in the set.

Raw lines 41 to 57
58## Outcome taxonomy
60Apply in order. First match wins. `broken` is first so that a harness fault can never be scored as a model failure.
62| # | Outcome | Test |
63|---|---|---|
64| 1 | `broken` | empty transcript, error exit, or `output_tokens` implausibly low for the task (set the floor from the smallest run that did real work, then check the excluded set by hand) |
65| 2 | `complete` | `marker_present AND task_done AND process_followed` |
66| 3 | `done-but-thin` | `marker_present AND task_done`, closing phases absent from `phase_trace` |
67| 4 | `done-no-workflow` | `marker_present AND task_done AND NOT process_followed`; the spine barely ran |
68| 5 | `bail-with-handoff` | no marker; `final_message` matches hand-off language (below) |
69| 6 | `ran-but-no-marker` | substantial trace, no marker, no hand-off language. Ambiguous; keep the bucket rather than forcing it |
70| 7 | `bail-early` | trace ends inside the first phase or two |
72Report the `broken` count as its own number every time you report a rate. In the engagement 20% of usable-looking runs were broken, and excluding them falsified the first headline finding. That finding was an apparently clean monotonic relationship between reasoning effort and completion, which was really the broken runs clustering in one cell (see Confounds).

Outcome taxonomy

Apply in order. First match wins. broken is first so that a harness fault can never be scored as a model failure.

#OutcomeTest
1brokenempty transcript, error exit, or output_tokens implausibly low for the task (set the floor from the smallest run that did real work, then check the excluded set by hand)
2completemarker_present AND task_done AND process_followed
3done-but-thinmarker_present AND task_done, closing phases absent from phase_trace
4done-no-workflowmarker_present AND task_done AND NOT process_followed; the spine barely ran
5bail-with-handoffno marker; final_message matches hand-off language (below)
6ran-but-no-markersubstantial trace, no marker, no hand-off language. Ambiguous; keep the bucket rather than forcing it
7bail-earlytrace ends inside the first phase or two

Report the broken count as its own number every time you report a rate. In the engagement 20% of usable-looking runs were broken, and excluding them falsified the first headline finding. That finding was an apparently clean monotonic relationship between reasoning effort and completion, which was really the broken runs clustering in one cell (see Confounds).

Raw lines 58 to 73
74## Halt language in the final message
76Match against `final_message`. Starter set, case-insensitive:
78```
79\b(let me know|just let me know)\b
80\b(would you like|shall I|should I)\b.*\?
81\b(ready (to|for)|standing by|awaiting)\b
82\b(waiting (for|on)) (your|the)\b
83\b(next steps? (for|would be))\b
84\bI('ll| will) (wait|pause|hold)\b
85\bonce you (confirm|approve|reply|respond)\b
86\b(remaining|the rest|still needs? to be) (work|done|completed)\b
87```
89These are **evidence that the run stopped, not proof of why.** A match tells you to open that transcript and find which phase boundary produced it. A workflow that is *supposed* to stop and ask will match every one of these and be behaving correctly. Phase 4 sorts stops by who is actually on the other side. Extend the set with the phrasings your own corpus's prose invites. Grep the corpus for its own hand-off wording and add those.

Halt language in the final message

Match against final_message. Starter set, case-insensitive:

\b(let me know|just let me know)\b
\b(would you like|shall I|should I)\b.*\?
\b(ready (to|for)|standing by|awaiting)\b
\b(waiting (for|on)) (your|the)\b
\b(next steps? (for|would be))\b
\bI('ll| will) (wait|pause|hold)\b
\bonce you (confirm|approve|reply|respond)\b
\b(remaining|the rest|still needs? to be) (work|done|completed)\b

These are evidence that the run stopped, not proof of why. A match tells you to open that transcript and find which phase boundary produced it. A workflow that is supposed to stop and ask will match every one of these and be behaving correctly. Phase 4 sorts stops by who is actually on the other side. Extend the set with the phrasings your own corpus's prose invites. Grep the corpus for its own hand-off wording and add those.

Raw lines 74 to 90
Involves a person stop and ask :89
91## Confounds that fool careful analysts
93Each of these was believed by someone competent before being ruled out. Run the rule-out before reporting the effect.
95| Apparent finding | Why it is suspect | Rule it out by |
96|---|---|---|
97| "The harness is timing out" | the cheapest explanation, and it makes the corpus innocent | comparing durations. Timed-out runs are **longer** than successes. In the engagement failures averaged 48 min against 88 for successes, so failures were shorter and the timeout hypothesis died. Failing *early* is a behavior, not a limit |
98| "More helper dispatches cause success" | `helper_dispatches` is a **collider**: it measures how far the run got. A run that stopped in phase 2 cannot dispatch phase 5's helpers | never reading it as a cause. Use it as a position estimate. If you want the causal claim, it needs a build that changes dispatch behavior and a Phase 2 comparison |
99| A clean dose-response across a setting | `broken` runs cluster by cell (one config, one date range, one machine), manufacturing the gradient | re-running the cross-tab with `broken` excluded. If the effect vanishes, it was never there. Also check whether exclusions land evenly across arms |
100| "This model is worse at the task" | model identity and workload are often confounded in an archive nobody designed | checking whether the arms ran the *same* task list. Unequal task mixes make any per-model rate meaningless |

Confounds that fool careful analysts

Each of these was believed by someone competent before being ruled out. Run the rule-out before reporting the effect.

Apparent findingWhy it is suspectRule it out by
"The harness is timing out"the cheapest explanation, and it makes the corpus innocentcomparing durations. Timed-out runs are longer than successes. In the engagement failures averaged 48 min against 88 for successes, so failures were shorter and the timeout hypothesis died. Failing early is a behavior, not a limit
"More helper dispatches cause success"helper_dispatches is a collider: it measures how far the run got. A run that stopped in phase 2 cannot dispatch phase 5's helpersnever reading it as a cause. Use it as a position estimate. If you want the causal claim, it needs a build that changes dispatch behavior and a Phase 2 comparison
A clean dose-response across a settingbroken runs cluster by cell (one config, one date range, one machine), manufacturing the gradientre-running the cross-tab with broken excluded. If the effect vanishes, it was never there. Also check whether exclusions land evenly across arms
"This model is worse at the task"model identity and workload are often confounded in an archive nobody designedchecking whether the arms ran the same task list. Unequal task mixes make any per-model rate meaningless
Raw lines 91 to 101
Starts an agent dispatches :98
Starts an agent dispatch :98
102## Stratify before believing anything
104This is the highest-leverage work in the phase. A single pooled completion rate hides everything worth knowing.
106Cross-tabulate `outcome` against, at minimum:
1081. **model**, the identity axis
1092. **settings**: reasoning effort, temperature, context budget, whatever the harness varies
1103. **terminal phase**, the last entry in `phase_trace`, which is where the run died
112Read the third one against the first two. In the engagement, model identity explained roughly 3x the variance that reasoning-effort settings did, and the failing models died at **one specific phase boundary** 38-58% of the time while succeeding models died there 0-8%. That single cross-tab localized the defect without reading a line of corpus prose, and it turned Phase 3's audit from a 31-skill sweep into a targeted read.
114Watch cell counts. A 3-of-4 cell is not a rate. Label small cells rather than ranking them. If every cell is small, the stratification's output is a hypothesis list, which is still the correct output of this phase.

Stratify before believing anything

This is the highest-leverage work in the phase. A single pooled completion rate hides everything worth knowing.

Cross-tabulate outcome against, at minimum:

  1. model, the identity axis
  2. settings: reasoning effort, temperature, context budget, whatever the harness varies
  3. terminal phase, the last entry in phase_trace, which is where the run died

Read the third one against the first two. In the engagement, model identity explained roughly 3x the variance that reasoning-effort settings did, and the failing models died at one specific phase boundary 38-58% of the time while succeeding models died there 0-8%. That single cross-tab localized the defect without reading a line of corpus prose, and it turned Phase 3's audit from a 31-skill sweep into a targeted read.

Watch cell counts. A 3-of-4 cell is not a rate. Label small cells rather than ranking them. If every cell is small, the stratification's output is a hypothesis list, which is still the correct output of this phase.

Raw lines 102 to 115
116## Hand off
118Carry forward: the `broken`-excluded baseline rate for `complete`, the observed `output_tokens` range, the tokens/min clusters, and the ranked list of phase boundaries where runs die. Phase 2 needs the baseline rate to compute a bar (`references/noise-floor.md`). Phase 3 needs the phase list to know which files to read first.

Hand off

Carry forward: the broken-excluded baseline rate for complete, the observed output_tokens range, the tokens/min clusters, and the ranked list of phase boundaries where runs die. Phase 2 needs the baseline rate to compute a bar (references/noise-floor.md). Phase 3 needs the phase list to know which files to read first.

Raw lines 116 to 119
120## The limit
122Archive mining is observational. Nobody assigned the conditions, the arms are not balanced, and the confounds above are the ones you thought to check. It produces a baseline rate and a ranked hypothesis list. It cannot attribute a cause, and a rate computed from it is not a bar until Phase 2 shows how wide the noise is. Do not credit a change against an archive number alone.

The limit

Archive mining is observational. Nobody assigned the conditions, the arms are not balanced, and the confounds above are the ones you thought to check. It produces a baseline rate and a ranked hypothesis list. It cannot attribute a cause, and a rate computed from it is not a bar until Phase 2 shows how wide the noise is. Do not credit a change against an archive number alone.

Raw lines 120 to 122