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.
package/dist/tasks.d.ts CHANGED
@@ -42,13 +42,20 @@ export interface TaskFunnel {
42
42
  unobservable: number;
43
43
  /** The first task that was NOT observed complete: where this participant stopped. */
44
44
  stoppedAt?: string;
45
- /** Per-task, in declaration order. */
45
+ /** Per-task, in declaration order. `inputsObserved` is false when the task declares criteria
46
+ * whose inputs (url, text, appState) NEVER arrived in any observation this session, so the
47
+ * task was never actually measured. Absent when the task completed or is unobservable. */
46
48
  tasks: Array<{
47
49
  id: string;
48
50
  completed: boolean;
49
51
  observable: boolean;
50
52
  turn?: number;
53
+ inputsObserved?: boolean;
51
54
  }>;
55
+ /** Observable tasks that were never measured, because the inputs their criteria need never
56
+ * arrived. Reported SEPARATELY from failures: a task nobody could observe is a gap in our
57
+ * instrument, and reporting it as 0-completed blames the participant for it (#514). */
58
+ unmeasured: number;
52
59
  }
53
60
  /**
54
61
  * Tracks task completion across a session. Stateful on purpose: a task completes ONCE, on the first
@@ -58,9 +65,15 @@ export interface TaskFunnel {
58
65
  export declare class TaskTracker {
59
66
  private readonly tasks;
60
67
  private readonly completions;
68
+ /** Which observation fields were ever populated this session. A criterion whose field never
69
+ * arrived was never evaluated against anything, however many turns ran (#514). */
70
+ private readonly fieldsSeen;
61
71
  constructor(tasks: readonly LabTask[]);
62
72
  /** Evaluate every still-incomplete task against one observation. Returns newly completed tasks. */
63
73
  observe(observation: StopConditionObservation, turn: number): TaskCompletion[];
74
+ /** Which observation fields a task's criteria actually read. A task whose rules need `url` was
75
+ * never measured if no observation ever carried one. */
76
+ private fieldsRequiredBy;
64
77
  /** The funnel as it stands. */
65
78
  funnel(): TaskFunnel;
66
79
  }
package/dist/tasks.js CHANGED
@@ -25,11 +25,20 @@ export const TASK_FUNNEL_SCHEMA = "humanish.task-funnel.v1";
25
25
  export class TaskTracker {
26
26
  tasks;
27
27
  completions = new Map();
28
+ /** Which observation fields were ever populated this session. A criterion whose field never
29
+ * arrived was never evaluated against anything, however many turns ran (#514). */
30
+ fieldsSeen = new Set();
28
31
  constructor(tasks) {
29
32
  this.tasks = tasks;
30
33
  }
31
34
  /** Evaluate every still-incomplete task against one observation. Returns newly completed tasks. */
32
35
  observe(observation, turn) {
36
+ if (observation.url !== undefined)
37
+ this.fieldsSeen.add("url");
38
+ if (observation.text !== undefined)
39
+ this.fieldsSeen.add("text");
40
+ if (observation.appState !== undefined)
41
+ this.fieldsSeen.add("appState");
33
42
  const fresh = [];
34
43
  for (const task of this.tasks) {
35
44
  if (task.success === undefined || this.completions.has(task.id))
@@ -48,26 +57,55 @@ export class TaskTracker {
48
57
  }
49
58
  return fresh;
50
59
  }
60
+ /** Which observation fields a task's criteria actually read. A task whose rules need `url` was
61
+ * never measured if no observation ever carried one. */
62
+ fieldsRequiredBy(task) {
63
+ const rules = task.success?.any ?? [];
64
+ const required = new Set();
65
+ for (const rule of rules) {
66
+ if (rule.urlIncludes !== undefined)
67
+ required.add("url");
68
+ if (rule.textIncludes !== undefined)
69
+ required.add("text");
70
+ if (rule.appStatePathEquals !== undefined)
71
+ required.add("appState");
72
+ }
73
+ return [...required];
74
+ }
51
75
  /** The funnel as it stands. */
52
76
  funnel() {
53
77
  const tasks = this.tasks.map((task) => {
54
78
  const completion = this.completions.get(task.id);
79
+ const observable = task.success !== undefined;
80
+ // A task counts as measured when at least ONE field its criteria read was populated by some
81
+ // observation. `any` semantics: any satisfiable rule needed a field we actually saw.
82
+ const required = observable ? this.fieldsRequiredBy(task) : [];
83
+ const inputsObserved = required.length === 0
84
+ ? true
85
+ : required.some((field) => this.fieldsSeen.has(field));
55
86
  return {
56
87
  id: task.id,
57
88
  completed: completion !== undefined,
58
- observable: task.success !== undefined,
59
- ...(completion === undefined ? {} : { turn: completion.turn })
89
+ observable,
90
+ ...(completion === undefined ? {} : { turn: completion.turn }),
91
+ // Only interesting for an observable task that did not complete: that is the case a
92
+ // reader would otherwise misread as a participant failure.
93
+ ...(observable && completion === undefined ? { inputsObserved } : {})
60
94
  };
61
95
  });
62
96
  // Where they stopped is the first task not observed complete — the thing a researcher reads
63
97
  // first. An unobservable task cannot be "where they stopped", because nothing could have
64
98
  // proven otherwise; skipping it avoids blaming a participant for a gap in the protocol.
65
- const stoppedAt = tasks.find((task) => task.observable && !task.completed)?.id;
99
+ // A task we never measured cannot be "where they stopped" either, for the same reason an
100
+ // unobservable one cannot: nothing could have proven otherwise, so naming it blames the
101
+ // participant for our gap (#514).
102
+ const stoppedAt = tasks.find((task) => task.observable && !task.completed && task.inputsObserved !== false)?.id;
66
103
  return {
67
104
  schema: TASK_FUNNEL_SCHEMA,
68
105
  total: tasks.length,
69
106
  completed: tasks.filter((task) => task.completed).length,
70
107
  unobservable: tasks.filter((task) => !task.observable).length,
108
+ unmeasured: tasks.filter((task) => task.inputsObserved === false).length,
71
109
  ...(stoppedAt === undefined ? {} : { stoppedAt }),
72
110
  tasks
73
111
  };
@@ -96,6 +134,11 @@ export function formatTaskFunnel(funnel) {
96
134
  const unobservable = funnel.unobservable === 0
97
135
  ? ""
98
136
  : `, ${funnel.unobservable} with no completion criterion`;
99
- return `${base}${stopped}${unobservable}`;
137
+ // Named separately from failures. "0/3 completed" alone reads as "no participant managed it",
138
+ // which is the wrong story when the criterion was never evaluated against anything (#514).
139
+ const unmeasured = funnel.unmeasured === 0
140
+ ? ""
141
+ : `, ${funnel.unmeasured} NEVER MEASURED (the observations their criteria read never arrived)`;
142
+ return `${base}${stopped}${unobservable}${unmeasured}`;
100
143
  }
101
144
  //# sourceMappingURL=tasks.js.map
package/dist/tasks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  Date: 2026-06-02 (current-state note updated 2026-07-14)
4
4
 
5
5
  Status: reference map for the major contracts shipped through source version
6
- `0.63.0`; it is not an exhaustive inventory of command/result envelopes. Exported types,
6
+ `0.65.0`; it is not an exhaustive inventory of command/result envelopes. Exported types,
7
7
  schema constants, parsers, and validators in `src/` are authoritative. Rows
8
8
  marked "reserved" name layering intent only — no code emits or validates them
9
9
  yet. Do not emit a reserved schema.
@@ -29,7 +29,7 @@ study completed, reproduced, and produced a real accessibility finding via a
29
29
  keyboard-first participant
30
30
  ([docs/goals/email-gated-signup/receipts/](email-gated-signup/receipts/)).
31
31
 
32
- ## Current Program Truth (source `0.63.0`)
32
+ ## Current Program Truth (source `0.65.0`)
33
33
 
34
34
  The package source and repository implementation in this tree agree on these
35
35
  points:
@@ -2,7 +2,7 @@
2
2
 
3
3
  Status: public-safe contributor and agent ramp.
4
4
 
5
- Package/source version in this tree: `0.63.0` (2026-09-01). The Observer is phone-usable as a stated requirement (observer/AGENTS.md); interactive primitives start from Base UI. The Observer renderer is the observer/ workspace artifact only; the legacy string-concat renderer was deleted at cutover (#426), and rollback is a version pin to 0.42.0. The containment boundary introduced in
5
+ Package/source version in this tree: `0.65.0` (2026-09-01). The Observer is phone-usable as a stated requirement (observer/AGENTS.md); interactive primitives start from Base UI. The Observer renderer is the observer/ workspace artifact only; the legacy string-concat renderer was deleted at cutover (#426), and rollback is a version pin to 0.42.0. The containment boundary introduced in
6
6
  `0.15.1` remains in force: managed run and output paths bind to validated
7
7
  physical filesystem identities, and stored provider IDs are evidence, not
8
8
  cleanup authority. The bundled OSS meta-lab is dry-run only until
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.63.0",
3
+ "version": "0.65.0",
4
4
  "description": "Open-source-safe CLI for persona simulation, observer review, and public-safe feedback drafts.",
5
5
  "author": "Daniel G Wilson <daniel@danielgwilson.com>",
6
6
  "keywords": [