humanish 0.63.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -289,7 +289,12 @@ function laneSpecsAndPlan(config, opts = {}) {
289
289
  const simId = `sim-${String(i + 1).padStart(3, "0")}`;
290
290
  const streamId = `stream-${String(i + 1).padStart(3, "0")}`;
291
291
  const device = resolveLaneDevice(config, lane);
292
- const personaId = (roster ? lane?.persona : actor?.persona);
292
+ // A lane's persona FALLS BACK to actors[0].persona, matching this field's own doc comment
293
+ // in src/lab-config.ts and its sibling resolutions (stopWhen, reasoningEffort) two lines
294
+ // below. Reading only lane.persona when a roster was present meant every fan-out lane of
295
+ // every lab that declared actors[0].persona ran with no persona at all: no personaLine in
296
+ // the prompt, traitsApplied [], and nothing warned (#512).
297
+ const personaId = (lane?.persona ?? actor?.persona);
293
298
  const resolvedPersona = personaId === undefined ? undefined : opts.personas?.get(personaId);
294
299
  const composed = composeLaneInstructions({
295
300
  mission,
@@ -1218,7 +1223,13 @@ function stripNegatedNonBlockerPhrases(text) {
1218
1223
  return text
1219
1224
  .replace(/\bno\s+(?:real\s+|remaining\s+|actual\s+)?(?:blocker|blockers|blocking issue|blocking issues|error|errors|failure|failures)\s+(?:was\s+|were\s+)?(?:encountered|observed|found|hit|seen|reported|detected)\b/g, "")
1220
1225
  .replace(/\bwithout\s+(?:a\s+|any\s+)?(?:real\s+|remaining\s+|actual\s+)?(?:blocker|blockers|blocking issue|blocking issues|error|errors|failure|failures)\b/g, "")
1221
- .replace(/\bnot\s+(?:blocked|a blocker|an error|failed)\b/g, "");
1226
+ .replace(/\bnot\s+(?:blocked|a blocker|an error|failed)\b/g, "")
1227
+ // "No functional failures blocked me" downgraded a clean passing run to a lab failure on
1228
+ // 2026-09-01. The adjective list above is closed (real|remaining|actual), so an ordinary
1229
+ // qualifier like "functional" slipped through and the trailing verb "blocked" tripped the
1230
+ // scan. Allow up to two intervening words, and cover the verb form directly.
1231
+ .replace(/\bno\s+(?:\w+\s+){0,2}(?:blocker|blockers|blocking issues?|errors?|failures?|problems?|issues?)\b(?:\s+(?:blocked|stopped|prevented)\s+(?:me|us|it))?/g, " ")
1232
+ .replace(/\bnothing\s+(?:\w+\s+){0,2}(?:blocked|stopped|prevented)\s+(?:me|us|it)\b/g, " ");
1222
1233
  }
1223
1234
  /**
1224
1235
  * Remove double-quoted spans and markdown blockquote lines before the blocker scan, so a persona