evalstate HF Staff commited on
Commit
50e0e7c
·
verified ·
1 Parent(s): 77fbc9e

Viewer: fold many argument-value fields per call (atif-scan 43ae555) (part 2)

Browse files
Files changed (24) hide show
  1. rows/06-claude-code--fable-5--xhigh/trajectories/viewer.css +2 -0
  2. rows/06-claude-code--fable-5--xhigh/trajectories/viewer.js +19 -2
  3. rows/06-claude-code--fable-5--xhigh/viewer/evidence.js +21 -1
  4. rows/06-claude-code--fable-5--xhigh/viewer/viewer.css +2 -0
  5. rows/06-claude-code--fable-5--xhigh/viewer/viewer.js +19 -2
  6. rows/07-codex--gpt-5-5--xhigh/trajectories/evidence.js +21 -1
  7. rows/07-codex--gpt-5-5--xhigh/trajectories/viewer.css +2 -0
  8. rows/07-codex--gpt-5-5--xhigh/trajectories/viewer.js +19 -2
  9. rows/07-codex--gpt-5-5--xhigh/viewer/evidence.js +21 -1
  10. rows/07-codex--gpt-5-5--xhigh/viewer/viewer.css +2 -0
  11. rows/07-codex--gpt-5-5--xhigh/viewer/viewer.js +19 -2
  12. rows/08-terminus-2--fable-5--high/trajectories/evidence.js +21 -1
  13. rows/08-terminus-2--fable-5--high/trajectories/viewer.css +2 -0
  14. rows/08-terminus-2--fable-5--high/trajectories/viewer.js +19 -2
  15. rows/08-terminus-2--fable-5--high/viewer/evidence.js +21 -1
  16. rows/08-terminus-2--fable-5--high/viewer/viewer.css +2 -0
  17. rows/08-terminus-2--fable-5--high/viewer/viewer.js +19 -2
  18. rows/09-cursor-cli--grok-4-5--high/trajectories/evidence.js +21 -1
  19. rows/09-cursor-cli--grok-4-5--high/trajectories/viewer.css +2 -0
  20. rows/09-cursor-cli--grok-4-5--high/trajectories/viewer.js +19 -2
  21. rows/09-cursor-cli--grok-4-5--high/viewer/evidence.js +21 -1
  22. rows/09-cursor-cli--grok-4-5--high/viewer/viewer.css +2 -0
  23. rows/09-cursor-cli--grok-4-5--high/viewer/viewer.js +19 -2
  24. rows/10-claude-code--opus-4-8--high/trajectories/evidence.js +21 -1
rows/06-claude-code--fable-5--xhigh/trajectories/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/06-claude-code--fable-5--xhigh/trajectories/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/06-claude-code--fable-5--xhigh/viewer/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/06-claude-code--fable-5--xhigh/viewer/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/06-claude-code--fable-5--xhigh/viewer/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/07-codex--gpt-5-5--xhigh/trajectories/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/07-codex--gpt-5-5--xhigh/trajectories/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/07-codex--gpt-5-5--xhigh/trajectories/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/07-codex--gpt-5-5--xhigh/viewer/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/07-codex--gpt-5-5--xhigh/viewer/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/07-codex--gpt-5-5--xhigh/viewer/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/08-terminus-2--fable-5--high/trajectories/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/08-terminus-2--fable-5--high/trajectories/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/08-terminus-2--fable-5--high/trajectories/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/08-terminus-2--fable-5--high/viewer/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/08-terminus-2--fable-5--high/viewer/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/08-terminus-2--fable-5--high/viewer/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/09-cursor-cli--grok-4-5--high/trajectories/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/09-cursor-cli--grok-4-5--high/trajectories/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/09-cursor-cli--grok-4-5--high/trajectories/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/09-cursor-cli--grok-4-5--high/viewer/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
rows/09-cursor-cli--grok-4-5--high/viewer/viewer.css CHANGED
@@ -138,3 +138,5 @@ footer.notes p{margin:4px 0}
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
 
 
 
138
  .answer-reason p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}
139
  .answer-reason-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;opacity:.75}
140
  .chip--plain{color:var(--ink)}
141
+ .fold{display:block;width:100%;text-align:left;border:0;border-top:1px dashed var(--line-soft);background:transparent;color:var(--muted);font-size:12.5px;padding:7px 14px;cursor:pointer}
142
+ .fold:hover{background:var(--inset);color:var(--ink)}
rows/09-cursor-cli--grok-4-5--high/viewer/viewer.js CHANGED
@@ -59,7 +59,7 @@
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
- priority: "", check: "" };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
@@ -86,6 +86,11 @@
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
 
 
 
 
 
89
  function flaggedSteps(trial) {
90
  const flagged = new Set();
91
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
@@ -336,7 +341,19 @@
336
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
337
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
338
  card.append(head, node("p", E.stepSummary(s), "step-title"));
339
- s.fields.forEach(f => card.append(fieldButton(s, f, E.sameField(state.ref, { step: s.step, ...f }))));
 
 
 
 
 
 
 
 
 
 
 
 
340
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
341
  return card;
342
  }));
 
59
  const scoredTrials = trials.filter(E.counted);
60
  const state = { trial: null, ref: null, span: null, finding: null, offset: 0,
61
  filter: scoredTrials.some(E.needsAttention) ? "attention" : "all", tab: "findings", allSteps: false,
62
+ priority: "", check: "", unfolded: new Set() };
63
 
64
  // Review mode: a blind human-review export. Verdicts are kept in this browser's local
65
  // storage (keyed by the export ID) and leave only as a file the reviewer downloads.
 
86
  const step = trial.steps.find(s => s.fields.length);
87
  return step ? refOf({ step: step.step, ...step.fields[0] }) : null;
88
  }
89
+ function locatedFields(trial) {
90
+ const keys = new Set();
91
+ for (const f of trial.findings) for (const l of f.locations) keys.add(`${l.step}:${l.part}:${l.index ?? 0}:${l.field ?? 0}`);
92
+ return keys;
93
+ }
94
  function flaggedSteps(trial) {
95
  const flagged = new Set();
96
  for (const f of trial.findings) for (const loc of f.locations) flagged.add(loc.step);
 
341
  const head = button("", () => jump(firstRef({ steps: [s] }), null, null), "step-head");
342
  head.append(node("strong", "STEP " + s.step), node("span", s.role));
343
  card.append(head, node("p", E.stepSummary(s), "step-title"));
344
+ const located = locatedFields(trial);
345
+ const keep = f => E.sameField(state.ref, { step: s.step, ...f }) || located.has(`${s.step}:${f.part}:${f.index}:${f.field}`);
346
+ for (const item of E.groupFields(s, keep)) {
347
+ if (item.field) { card.append(fieldButton(s, item.field, E.sameField(state.ref, { step: s.step, ...item.field }))); continue; }
348
+ if (state.unfolded.has(item.key)) {
349
+ item.folded.forEach(f => card.append(fieldButton(s, f, false)));
350
+ card.append(button(`Fold ${item.folded.length} argument values`, () => { state.unfolded.delete(item.key); renderTimeline(); }, "fold"));
351
+ } else {
352
+ const chars = item.folded.reduce((n, f) => n + E.length(f), 0);
353
+ card.append(button(`call ${item.call} · ${item.folded.length} more argument values · ${chars.toLocaleString("en")} chars`,
354
+ () => { state.unfolded.add(item.key); renderTimeline(); }, "fold"));
355
+ }
356
+ }
357
  if (flagged.has(s.step)) { const flags = node("div", undefined, "badges step-flags"); flags.append(badge("finding")); card.append(flags); }
358
  return card;
359
  }));
rows/10-claude-code--opus-4-8--high/trajectories/evidence.js CHANGED
@@ -473,7 +473,27 @@
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
- const api = { judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
478
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
479
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };
 
473
  if (row.thin) facts.push("a universal answer after reading under half: a guess about the rest");
474
  return facts;
475
  }
476
+ // A call's minor argument fields (each string leaf of its arguments, e.g. a parsed shell
477
+ // command's words) fold behind one row when there are many, so the step reads as its calls.
478
+ // `keep(field)` names fields that must stay visible (the selected one, finding locations).
479
+ const FOLD_MIN = 3;
480
+ function groupFields(step, keep = () => false) {
481
+ const out = [], byCall = new Map();
482
+ for (const f of step.fields) {
483
+ if (f.part !== "call") { out.push({ field: f }); continue; }
484
+ if (!byCall.has(f.index)) { byCall.set(f.index, []); out.push({ call: f.index }); }
485
+ byCall.get(f.index).push(f);
486
+ }
487
+ return out.flatMap(item => {
488
+ if (!("call" in item)) return [item];
489
+ const fields = byCall.get(item.call);
490
+ const minor = fields.filter(f => f.channel === "arguments" && !keep(f));
491
+ if (minor.length < FOLD_MIN) return fields.map(f => ({ field: f }));
492
+ const shown = fields.filter(f => !minor.includes(f)).map(f => ({ field: f }));
493
+ return [...shown, { folded: minor, call: item.call, key: `${step.step}:${item.call}` }];
494
+ });
495
+ }
496
+ const api = { groupFields, FOLD_MIN, judgeConcerns, answerTone, answerFacts, MAX_NOTE, reviewKey, validVerdict, isPositive, mechanismFor, reviewProgress, reviewExport, PAGE_SIZE, MAX_HITS, PRIORITY, sameField, locate, page, highlighted, focusOffset, clip,
497
  context, literalMatches, search, ordered, isLead, hasGap, topPriority, rewardLabel,
498
  needsAttention, stepSummary, family, checkIndex, matchesFilters, byPriority, coverageLines, focusNote, charLabel, length, unreadText,
499
  compact, usd, duration, costHeadline, harnessLine, trialFacts, calcLines, runRecordsNote, unknownLead, errorClass, outcome, CLASS_LABEL, counted, lineageNote };