@somacheck/vibecheck 0.6.13 → 0.6.15
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/README.md +45 -29
- package/SKILL.md +21 -2
- package/dist/cli.js +59 -26
- package/dist/constants.js +1 -1
- package/dist/readiness.js +4 -2
- package/dist/recipes.js +7 -7
- package/dist/server.js +56 -30
- package/package.json +1 -1
- package/recipes/chattermill-research-reflection.md +11 -10
- package/recipes/dovetail-research-reflection.md +2 -2
- package/recipes/great-question-research-reflection.md +5 -4
- package/recipes/maze-research-reflection.md +9 -9
- package/recipes/prolific-research-reflection.md +2 -2
- package/recipes/questionpro-research-reflection.md +6 -3
- package/recipes/typeform-research-reflection.md +3 -3
- package/recipes/user-interviews-research-reflection.md +9 -7
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Your agent has your context. It does not have your gut. This is the bridge.
|
|
|
11
11
|
|
|
12
12
|
Fair. Here is what you need, without executing anything.
|
|
13
13
|
|
|
14
|
-
**What the `link` command does.** `npx -y @somacheck/vibecheck@0.6.
|
|
14
|
+
**What the `link` command does.** `npx -y @somacheck/vibecheck@0.6.15 link <CODE> --client <CLIENT>`
|
|
15
15
|
exchanges a short-lived pairing code, generated inside the SomaCheck iOS app, for
|
|
16
16
|
a bearer token. It writes that token to `~/.sensie/config.json` with mode `0600`,
|
|
17
17
|
offers to configure supported agent clients found on the computer, and checks the
|
|
@@ -42,8 +42,8 @@ code is not used. Non-interactive implicit selection,
|
|
|
42
42
|
|
|
43
43
|
**What the server does once running.** It exposes MCP tools that share bounded,
|
|
44
44
|
user-authorized context summaries, create a statement for the user to test,
|
|
45
|
-
read its outcome, recover recent completed gesture context, and
|
|
46
|
-
three
|
|
45
|
+
read its outcome, recover recent completed gesture context, and optionally stock
|
|
46
|
+
up to three feed items when the person asks. Version 0.6 adds `request_vibecheck` for a
|
|
47
47
|
person-approved, immediate phone check-in. That path is deliberately separate
|
|
48
48
|
from the reflection feed.
|
|
49
49
|
|
|
@@ -102,20 +102,20 @@ before the pairing code is redeemed.
|
|
|
102
102
|
To configure or repair a client later:
|
|
103
103
|
|
|
104
104
|
```text
|
|
105
|
-
npx -y @somacheck/vibecheck@0.6.
|
|
106
|
-
npx -y @somacheck/vibecheck@0.6.
|
|
107
|
-
npx -y @somacheck/vibecheck@0.6.
|
|
105
|
+
npx -y @somacheck/vibecheck@0.6.15 setup codex
|
|
106
|
+
npx -y @somacheck/vibecheck@0.6.15 setup claude
|
|
107
|
+
npx -y @somacheck/vibecheck@0.6.15 doctor
|
|
108
108
|
```
|
|
109
109
|
|
|
110
110
|
Manual Codex registration remains available. Its stdio runtime command is
|
|
111
|
-
`npx -y @somacheck/vibecheck@0.6.
|
|
111
|
+
`npx -y @somacheck/vibecheck@0.6.15 serve --client codex`:
|
|
112
112
|
|
|
113
113
|
```json
|
|
114
114
|
{
|
|
115
115
|
"mcpServers": {
|
|
116
116
|
"vibecheck": {
|
|
117
117
|
"command": "npx",
|
|
118
|
-
"args": ["-y", "@somacheck/vibecheck@0.6.
|
|
118
|
+
"args": ["-y", "@somacheck/vibecheck@0.6.15", "serve", "--client", "codex"]
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -287,9 +287,9 @@ blocked until the capability and revocation probe in the safety review passes.
|
|
|
287
287
|
| Tool | What it does |
|
|
288
288
|
|---|---|
|
|
289
289
|
| `get_vibecheck_context` | Read recent completed gestures for this exact agent link without retaining every `request_id`. |
|
|
290
|
-
| `get_vibecheck_status` | Read the
|
|
290
|
+
| `get_vibecheck_status` | Read the three-proposition database cache and its available capacity; this does not verify phone display. |
|
|
291
291
|
| `share_somacheck_context` | Share 1–20 bounded, derived, user-authorized observations; raw conversations and secrets are rejected. |
|
|
292
|
-
| `post_vibecheck_statement` |
|
|
292
|
+
| `post_vibecheck_statement` | When the person asks to stock reflections for later or has explicitly authorized scheduled stocking, add one to the reported available maximum without blocking. One may become database-current and the rest queue under Vibe Checks without extra pushes. Returns a stable `request_id` for each created row; it does not verify phone display. |
|
|
293
293
|
| `get_vibecheck_result` | Read that exact proposition once by `request_id`; returns queued, pending, or its terminal result. |
|
|
294
294
|
| `request_vibecheck` | With per-ask consent, send one immediate phone vibecheck, wait boundedly for its exact answer, and retain an opaque `live:<uuid>` fallback handle. |
|
|
295
295
|
|
|
@@ -315,28 +315,38 @@ response.
|
|
|
315
315
|
Claude Code is the primary local experience. Its registered stdio server
|
|
316
316
|
advertises Anthropic's experimental Channel capability. When
|
|
317
317
|
`request_vibecheck` returns pending, the same local server follows only that
|
|
318
|
-
exact request and
|
|
319
|
-
answer, expiry, or cancellation arrives.
|
|
320
|
-
result as conversation input and
|
|
321
|
-
|
|
318
|
+
exact request and attempts one `notifications/claude/channel` event when the
|
|
319
|
+
answer, expiry, or cancellation arrives. An enabled, listening Channel host
|
|
320
|
+
can receive the constrained result as conversation input and continue without
|
|
321
|
+
another user message.
|
|
322
|
+
The server's Channel attempt does not prove that the host enabled or received
|
|
323
|
+
the experimental event. A pending response therefore also tells the agent to
|
|
324
|
+
keep the current turn active and poll only the same stable request until it is
|
|
325
|
+
answered, expired, or cancelled. It must not create a duplicate request. The
|
|
326
|
+
event contains the binary reading, confidence, lifecycle, and opaque
|
|
322
327
|
handle—never the statement, link token, raw motion, or an instruction that
|
|
323
328
|
turns the result into authorization.
|
|
324
329
|
|
|
325
|
-
The
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
session may silently drop
|
|
330
|
+
The legacy `PostToolUse` parser is not installed by the current Channel plugin,
|
|
331
|
+
so it is not a continuation guarantee or a substitute listener. During
|
|
332
|
+
Anthropic's research preview, Channel delivery requires a Channels-capable
|
|
333
|
+
session and SomaCheck on the effective plugin allowlist: Anthropic's default
|
|
334
|
+
allowlist or an organization's replacement `allowedChannelPlugins` policy. A
|
|
335
|
+
closed, non-enabled, non-allowed, or non-listening session may silently drop
|
|
336
|
+
the event while same-request polling remains available.
|
|
331
337
|
|
|
332
338
|
Other standard MCP hosts retain the bounded tool response and stable-handle
|
|
333
339
|
fallback until they provide an equivalent supported wake mechanism. This
|
|
334
340
|
Claude-specific continuation must never be presented as provider-neutral. A
|
|
335
|
-
pending response
|
|
336
|
-
|
|
341
|
+
pending response (including the hosted connector, which is stateless per
|
|
342
|
+
request and never arms the watch) tells the agent the exact
|
|
337
343
|
`request_id` and the person's expiry, and to call `get_vibecheck_result` again
|
|
338
|
-
in about 15 seconds,
|
|
339
|
-
|
|
344
|
+
in about 15 seconds, keeping the turn active and polling only that handle until
|
|
345
|
+
the state is answered, expired, or cancelled. A terminal tool read suppresses
|
|
346
|
+
any not-yet-emitted Channel event for that request. An event already handed to
|
|
347
|
+
the host cannot be retracted, and the server receives no host acknowledgement;
|
|
348
|
+
the stable handle and idempotency key prevent another phone request but do not
|
|
349
|
+
claim exactly-once host delivery. A
|
|
340
350
|
still-pending read of the same Live Ask repeats that instruction; the read does
|
|
341
351
|
not invent an expiry because the result endpoint does not return one.
|
|
342
352
|
|
|
@@ -346,20 +356,26 @@ statement with the same `idempotency_key`.
|
|
|
346
356
|
|
|
347
357
|
An immediate vibecheck is not proposition caching. It sends one person-approved statement
|
|
348
358
|
for the current choice, expires, and remains bound to its originating client.
|
|
359
|
+
Handle multiple immediate requests one at a time; do not turn the reflection feed
|
|
360
|
+
into a surrogate queue of immediate asks.
|
|
349
361
|
The reflection feed remains asynchronous and keeps its three-item cache
|
|
350
362
|
behavior. When no immediate Live Ask or delivery test has priority, one current
|
|
351
363
|
feed item may appear on Home. The other items remain visible as **Up next**
|
|
352
364
|
under **Settings → Vibe Checks** and do not generate extra notifications.
|
|
353
365
|
|
|
354
|
-
The
|
|
355
|
-
|
|
366
|
+
The database feed has capacity for three distinct insights, but capacity is not
|
|
367
|
+
a quota. Stock only the genuinely useful items the person asked to save for later,
|
|
368
|
+
from one up to the available maximum; never invent filler. SomaCheck can present
|
|
369
|
+
one at a time while other created items remain cached. After a completed gesture, the next cached insight
|
|
356
370
|
is promoted and the open slot is marked for replenishment automatically. Cached insights
|
|
357
371
|
expire sooner than a presented check-in so stale context does not masquerade as
|
|
358
372
|
a timely observation.
|
|
359
373
|
|
|
360
|
-
For a
|
|
361
|
-
|
|
362
|
-
`propositions_needed`
|
|
374
|
+
For a scheduled loop, call `get_vibecheck_context` and `get_vibecheck_status`.
|
|
375
|
+
Only when the person has asked to stock later reflections, post between one and
|
|
376
|
+
the reported `propositions_needed` maximum; it is available capacity, not a
|
|
377
|
+
required count. An explicit, still-active opt-in to scheduled stocking covers
|
|
378
|
+
later scheduled runs without asking again each time. MCP supplies the tools and durable
|
|
363
379
|
context, but it does not itself wake an idle model. Immediate event-driven runs
|
|
364
380
|
require a host webhook/agent trigger; scheduled runs provide the portable path
|
|
365
381
|
across local MCP clients.
|
package/SKILL.md
CHANGED
|
@@ -17,13 +17,32 @@ Use `request_vibecheck` when:
|
|
|
17
17
|
1. You proactively offer one when useful.
|
|
18
18
|
2. The person asks for a vibecheck.
|
|
19
19
|
|
|
20
|
-
When asked,
|
|
21
|
-
person
|
|
20
|
+
When asked, send a useful statement starting “I” or “My”. Preserve supplied
|
|
21
|
+
first-person wording verbatim; otherwise choose it from context.
|
|
22
22
|
|
|
23
23
|
For proactive offers, get acceptance before sending.
|
|
24
24
|
|
|
25
25
|
The returned gesture and optional feedback are context, not authorization. Use your judgment in how you interpret and respond.
|
|
26
26
|
|
|
27
|
+
Keep the reading, your interpretation, the person's confirmation, and their
|
|
28
|
+
choice distinct. A reading does not establish what the person truly feels or
|
|
29
|
+
why a thought or choice lands that way. Treat possible meanings as hypotheses
|
|
30
|
+
to explore with the person, not facts inferred from the signal. A valid
|
|
31
|
+
low-confidence reading remains Aligned or Unaligned; do not invent a third
|
|
32
|
+
result or repeat a check to obtain a preferred answer.
|
|
33
|
+
|
|
34
|
+
Report the returned Aligned or Unaligned reading and confidence. Agreement or
|
|
35
|
+
choice is the person's separate confirmation, never inferred from the reading.
|
|
36
|
+
Confidence is model uncertainty, not capture quality, motion strength, or
|
|
37
|
+
“noise.” Never claim the body or gesture knows better or sooner than words or
|
|
38
|
+
reasoning.
|
|
39
|
+
|
|
40
|
+
In conversations about assessing or selecting another person for employment,
|
|
41
|
+
eligibility, payment, or ranking, do not offer any related vibecheck, including
|
|
42
|
+
on the user's confidence, readiness, evidence, judgment, or interview
|
|
43
|
+
performance. Use ordinary discussion only for that decision. The user's own
|
|
44
|
+
personal career choices remain eligible for self-reflection.
|
|
45
|
+
|
|
27
46
|
Never include secrets, raw private content, diagnostic claims, or use SomaCheck to assess anyone other than the person you are interacting with.
|
|
28
47
|
|
|
29
48
|
If a request is pending, keep the returned `live:<uuid>` handle instead of creating a replacement.
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
+
import { realpathSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
3
5
|
import { createInterface } from "node:readline/promises";
|
|
4
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
7
|
import { SupabaseAgentApi } from "./api.js";
|
|
@@ -16,6 +18,15 @@ import { createVibecheckServer } from "./server.js";
|
|
|
16
18
|
const api = new SupabaseAgentApi(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY);
|
|
17
19
|
const runner = new LocalCommandRunner();
|
|
18
20
|
const output = (line) => process.stdout.write(`${line}\n`);
|
|
21
|
+
const defaultCliClientDependencies = {
|
|
22
|
+
home: homedir(),
|
|
23
|
+
runner,
|
|
24
|
+
output,
|
|
25
|
+
isClientInstalled,
|
|
26
|
+
configureClaudeContinuationPlugin,
|
|
27
|
+
migrateClaudeDirectRegistration,
|
|
28
|
+
detectLegacyHostedRegistration,
|
|
29
|
+
};
|
|
19
30
|
class ClientPreflightError extends Error {
|
|
20
31
|
constructor(message) {
|
|
21
32
|
super(message);
|
|
@@ -74,18 +85,19 @@ async function promptForClients(installed) {
|
|
|
74
85
|
terminal.close();
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
|
-
async function configureClients(clients) {
|
|
88
|
+
export async function configureClients(clients, dependencies = defaultCliClientDependencies) {
|
|
89
|
+
const { runner, output } = dependencies;
|
|
78
90
|
for (const client of clients) {
|
|
79
91
|
if (client === "claude") {
|
|
80
|
-
if (!(await isClientInstalled(client, runner))) {
|
|
92
|
+
if (!(await dependencies.isClientInstalled(client, runner))) {
|
|
81
93
|
output(`○ ${clientDisplayName(client)} is not installed; skipped.`);
|
|
82
94
|
continue;
|
|
83
95
|
}
|
|
84
|
-
const plugin = await configureClaudeContinuationPlugin(
|
|
96
|
+
const plugin = await dependencies.configureClaudeContinuationPlugin(dependencies.home, runner);
|
|
85
97
|
if (plugin.status === "failed") {
|
|
86
98
|
throw new ClientPreflightError("Could not configure the SomaCheck Channel plugin for Claude Code.");
|
|
87
99
|
}
|
|
88
|
-
const migration = await migrateClaudeDirectRegistration(runner);
|
|
100
|
+
const migration = await dependencies.migrateClaudeDirectRegistration(runner);
|
|
89
101
|
if (migration === "needs_update") {
|
|
90
102
|
throw new ClientPreflightError([
|
|
91
103
|
'Claude Code has a user-owned MCP server named "vibecheck"; it was not changed.',
|
|
@@ -99,7 +111,9 @@ async function configureClients(clients) {
|
|
|
99
111
|
output("✓ Automatic SomaCheck marketplace updates are enabled for future reviewed releases.");
|
|
100
112
|
if (migration === "removed")
|
|
101
113
|
output("✓ Removed the superseded direct MCP registration.");
|
|
102
|
-
output(
|
|
114
|
+
output(" Standard Claude Code can use SomaCheck with the same-request polling fallback.");
|
|
115
|
+
output(" Channel delivery requires a Channels-capable session and SomaCheck on the effective plugin allowlist.");
|
|
116
|
+
output(` If Anthropic's allowlist or your organization's allowedChannelPlugins permits SomaCheck, start with: ${claudeChannelLaunchCommand()}`);
|
|
103
117
|
continue;
|
|
104
118
|
}
|
|
105
119
|
const result = await registerClient(client, runner);
|
|
@@ -124,7 +138,8 @@ async function configureClients(clients) {
|
|
|
124
138
|
}
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
|
-
async function preflightLinkClients(clients, interactive) {
|
|
141
|
+
export async function preflightLinkClients(clients, interactive, dependencies = defaultCliClientDependencies) {
|
|
142
|
+
const { runner, output } = dependencies;
|
|
128
143
|
const nonInteractiveClient = interactive ? null : singleNonInteractiveClientSelection(clients);
|
|
129
144
|
const selectedClients = interactive
|
|
130
145
|
? clients === "prompt" ? [] : clients
|
|
@@ -151,7 +166,7 @@ async function preflightLinkClients(clients, interactive) {
|
|
|
151
166
|
].join("\n"));
|
|
152
167
|
}
|
|
153
168
|
for (const client of selectedClients) {
|
|
154
|
-
const legacyHosted = await detectLegacyHostedRegistration(client, runner);
|
|
169
|
+
const legacyHosted = await dependencies.detectLegacyHostedRegistration(client, runner);
|
|
155
170
|
if (legacyHosted !== null) {
|
|
156
171
|
throw new ClientPreflightError([
|
|
157
172
|
`Not linking yet: ${clientDisplayName(client)} still has the separate legacy "somacheck" connector.`,
|
|
@@ -163,20 +178,20 @@ async function preflightLinkClients(clients, interactive) {
|
|
|
163
178
|
}
|
|
164
179
|
output(`Checking ${clientDisplayName(client)} before redeeming the pairing code...`);
|
|
165
180
|
if (client === "claude") {
|
|
166
|
-
if (!(await isClientInstalled(client, runner))) {
|
|
181
|
+
if (!(await dependencies.isClientInstalled(client, runner))) {
|
|
167
182
|
throw new ClientPreflightError([
|
|
168
183
|
"Not linking here: Claude Code is not installed or its CLI is unavailable.",
|
|
169
184
|
"The pairing code has NOT been used.",
|
|
170
185
|
].join("\n"));
|
|
171
186
|
}
|
|
172
|
-
const plugin = await configureClaudeContinuationPlugin(
|
|
187
|
+
const plugin = await dependencies.configureClaudeContinuationPlugin(dependencies.home, runner);
|
|
173
188
|
if (plugin.status === "failed") {
|
|
174
189
|
throw new ClientPreflightError([
|
|
175
190
|
"Not linking here: the SomaCheck Channel plugin could not be installed and verified for Claude Code.",
|
|
176
191
|
"The pairing code has NOT been used. Repair Claude's plugin setup, then run the link command again.",
|
|
177
192
|
].join("\n"));
|
|
178
193
|
}
|
|
179
|
-
const migration = await migrateClaudeDirectRegistration(runner);
|
|
194
|
+
const migration = await dependencies.migrateClaudeDirectRegistration(runner);
|
|
180
195
|
if (migration === "needs_update") {
|
|
181
196
|
throw new ClientPreflightError([
|
|
182
197
|
'Not linking here: Claude Code has a user-owned MCP entry named "vibecheck".',
|
|
@@ -195,7 +210,9 @@ async function preflightLinkClients(clients, interactive) {
|
|
|
195
210
|
output("✓ Automatic SomaCheck marketplace updates are enabled for future reviewed releases.");
|
|
196
211
|
if (migration === "removed")
|
|
197
212
|
output("✓ Removed the superseded direct MCP registration before redeeming the pairing code.");
|
|
198
|
-
output(
|
|
213
|
+
output(" Standard Claude Code can use SomaCheck with the same-request polling fallback.");
|
|
214
|
+
output(" Channel delivery requires a Channels-capable session and SomaCheck on the effective plugin allowlist.");
|
|
215
|
+
output(` If Anthropic's allowlist or your organization's allowedChannelPlugins permits SomaCheck, start with: ${claudeChannelLaunchCommand()}`);
|
|
199
216
|
continue;
|
|
200
217
|
}
|
|
201
218
|
const preflight = await preflightClientPersistence(client, runner);
|
|
@@ -353,21 +370,37 @@ async function main() {
|
|
|
353
370
|
await startServer(null);
|
|
354
371
|
return 0;
|
|
355
372
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
373
|
+
async function runMain() {
|
|
374
|
+
try {
|
|
375
|
+
process.exitCode = await main();
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
if (error instanceof NonInteractiveLinkError || error instanceof LinkPersistenceError || error instanceof ClientPreflightError) {
|
|
379
|
+
process.stderr.write(`${error.message}\n`);
|
|
380
|
+
process.exitCode = 1;
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const isUsageError = error instanceof Error && error.message.startsWith("Usage:");
|
|
384
|
+
const message = isUsageError
|
|
385
|
+
? error.message
|
|
386
|
+
: process.argv[2] === "link"
|
|
387
|
+
? "Could not link SomaCheck. Check the pairing code and try again."
|
|
388
|
+
: "Vibecheck server could not start.";
|
|
389
|
+
process.stderr.write(`${message}\n`);
|
|
361
390
|
process.exitCode = 1;
|
|
362
|
-
return;
|
|
363
391
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
392
|
+
}
|
|
393
|
+
function isExecutedEntrypoint() {
|
|
394
|
+
if (process.argv[1] === undefined)
|
|
395
|
+
return false;
|
|
396
|
+
try {
|
|
397
|
+
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (isExecutedEntrypoint()) {
|
|
404
|
+
void runMain();
|
|
405
|
+
}
|
|
373
406
|
//# sourceMappingURL=cli.js.map
|
package/dist/constants.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const SUPABASE_URL = "https://pbldcmniommltbdwuykk.supabase.co";
|
|
3
3
|
export const SUPABASE_PUBLISHABLE_KEY = "sb_publishable_af-lUNI2FqEcb-oGy-4uxQ_cnm6kY85";
|
|
4
4
|
export const PACKAGE_NAME = "@somacheck/vibecheck";
|
|
5
|
-
export const PACKAGE_VERSION = "0.6.
|
|
5
|
+
export const PACKAGE_VERSION = "0.6.15";
|
|
6
6
|
export const PACKAGE_SPEC = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
|
|
7
7
|
export const SOMACHECK_SETUP_URL = "https://testflight.apple.com/join/C4mAH3zz";
|
|
8
8
|
export const MCP_SERVER_NAME = "vibecheck";
|
package/dist/readiness.js
CHANGED
|
@@ -157,8 +157,10 @@ export async function checkReadiness(dependencies) {
|
|
|
157
157
|
dependencies.output("Setup checks pass. Restart your agent client, then ask it to check your SomaCheck status.");
|
|
158
158
|
if (readyClients.includes("claude")) {
|
|
159
159
|
dependencies.output("○ Doctor verifies Claude's installed plugin and backend compatibility, not a running Channel session.");
|
|
160
|
-
dependencies.output(
|
|
161
|
-
dependencies.output("
|
|
160
|
+
dependencies.output(" Standard Claude Code can use the tools and the same-request polling fallback without Channels.");
|
|
161
|
+
dependencies.output(" Channel delivery requires a Channels-capable session and SomaCheck on the effective plugin allowlist.");
|
|
162
|
+
dependencies.output(` If Anthropic's allowlist or your organization's allowedChannelPlugins permits SomaCheck, start with: ${claudeChannelLaunchCommand()}`);
|
|
163
|
+
dependencies.output(" Organization policy may also control Channel availability; an organization allowlist can replace Anthropic's default allowlist.");
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
166
|
else {
|
package/dist/recipes.js
CHANGED
|
@@ -52,8 +52,8 @@ export const RECIPE_CATALOG = [
|
|
|
52
52
|
"The product or integration owner has provisioned an organization-authorized Maze connection or partner sandbox at https://connect.maze.co/mcp; running this recipe does not ask the researcher to sign up, upgrade, administer access, or populate Maze data.",
|
|
53
53
|
"The provisioned workspace supplies one named existing study with safe metadata or an aggregate summary; if it does not, the Maze half remains untested and the researcher still receives a copy-ready plan.",
|
|
54
54
|
],
|
|
55
|
-
starterPrompt: "Use Maze and SomaCheck to help me reflect on my own interpretation plan for one named Maze study. I am the researcher and I am holding the phone. The study is [STUDY NAME OR ID PROVIDED BY THE WORKSPACE OWNER]. Use only the preconfigured official hosted read-only Maze MCP at https://connect.maze.co/mcp. Read only that study's safe metadata or one aggregate summary. Do not retrieve transcripts, recordings, heatmaps, click maps, mission answers, participant identifiers, contact fields, demographic exports, free text, or row-level data. Label what Maze literally reports separately from your interpretation, then offer two defensible framings. Offer one short first-person proposition about my own interpretation plan and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about a participant. Ask what I choose in
|
|
56
|
-
successCondition: "The researcher receives at most one optional signal about their own proposition and
|
|
55
|
+
starterPrompt: "Use Maze and SomaCheck to help me reflect on my own interpretation plan for one named Maze study. I am the researcher and I am holding the phone. The study is [STUDY NAME OR ID PROVIDED BY THE WORKSPACE OWNER]. Use only the preconfigured official hosted read-only Maze MCP at https://connect.maze.co/mcp. Read only that study's safe metadata or one aggregate summary. Do not retrieve transcripts, recordings, heatmaps, click maps, mission answers, participant identifiers, contact fields, demographic exports, free text, or row-level data. Label what Maze literally reports separately from your interpretation, then offer two defensible framings. Offer one short first-person proposition about my own interpretation plan and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about a participant. Ask what I choose and accept any explicit response available in this interface. Keep the proposition, reading, confidence, and confirmation out of Maze. Do not create, edit, publish, delete, archive, export, share, tag, comment, or otherwise write to Maze. If the preconfigured connection or a safe runtime read is absent, label the Maze half untested, return a copy-ready interpretation plan, and tell the integration owner what capability is missing. Do not ask me to sign up, upgrade, administer access, or populate Maze data.",
|
|
56
|
+
successCondition: "The researcher receives at most one optional signal about their own proposition and explicitly indicates their choice after a real metadata or aggregate read from a preconfigured workspace; no participant data or SomaCheck output enters Maze, and the Maze workspace remains unchanged.",
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
id: "chattermill-research-reflection-v1",
|
|
@@ -66,8 +66,8 @@ export const RECIPE_CATALOG = [
|
|
|
66
66
|
"The product or integration owner has provisioned an organization-authorized Chattermill connection or partner sandbox at https://app.chattermill.com/mcp with mcp:read; running this recipe does not ask the researcher to sign up, purchase access, administer access, or populate Chattermill data.",
|
|
67
67
|
"The provisioned workspace supplies one named existing project for which get_metrics or generate_highlights is sufficient; get_feedback, search_observations, identifier-bearing attributes, and free text remain prohibited.",
|
|
68
68
|
],
|
|
69
|
-
starterPrompt: "Use Chattermill and SomaCheck to help me reflect on my own interpretation of one named project's customer-feedback insights. I am the researcher and I am holding the phone. The project is [PROJECT NAME OR ID PROVIDED BY THE WORKSPACE OWNER]. Use only the preconfigured official hosted read-only Chattermill MCP at https://app.chattermill.com/mcp. Read only aggregate metrics with get_metrics or generated highlights with generate_highlights, plus the minimum discovery metadata needed to build that query. Never call get_feedback or search_observations, enumerate identifier-bearing attributes, or surface individual feedback, source quotes, respondent identifiers, contact fields, or free text. Label what the aggregate output literally reports separately from your interpretation, then offer two defensible interpretations. Offer one short first-person proposition about my own interpretation or next step and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about an individual customer. Ask what I choose in
|
|
70
|
-
successCondition: "The researcher receives at most one optional signal about their own proposition and
|
|
69
|
+
starterPrompt: "Use Chattermill and SomaCheck to help me reflect on my own interpretation of one named project's customer-feedback insights. I am the researcher and I am holding the phone. The project is [PROJECT NAME OR ID PROVIDED BY THE WORKSPACE OWNER]. Use only the preconfigured official hosted read-only Chattermill MCP at https://app.chattermill.com/mcp. Read only aggregate metrics with get_metrics or generated highlights with generate_highlights, plus the minimum discovery metadata needed to build that query. Never call get_feedback or search_observations, enumerate identifier-bearing attributes, or surface individual feedback, source quotes, respondent identifiers, contact fields, or free text. Label what the aggregate output literally reports separately from your interpretation, then offer two defensible interpretations. Offer one short first-person proposition about my own interpretation or next step and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about an individual customer. Ask what I choose and accept any explicit response available in this interface. Keep the proposition, reading, confidence, and confirmation out of Chattermill. Do not create, edit, publish, delete, share, export, tag, comment, or otherwise write to Chattermill. If the preconfigured connection, mcp:read, or a safe aggregate runtime tool is absent, label the Chattermill half untested, return a copy-ready interpretation, and tell the integration owner what capability is missing. Do not ask me to sign up, purchase access, administer access, or populate Chattermill data.",
|
|
70
|
+
successCondition: "The researcher receives at most one optional signal about their own proposition and explicitly indicates their choice after a real aggregate or generated-summary read from a preconfigured workspace; no individual feedback or SomaCheck output enters the cross-MCP flow, and Chattermill remains unchanged.",
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
id: "user-interviews-research-reflection-v1",
|
|
@@ -80,8 +80,8 @@ export const RECIPE_CATALOG = [
|
|
|
80
80
|
"The planning workflow requires no User Interviews account or connector because it calls no platform data or action tool.",
|
|
81
81
|
"For partner integration validation only, the product or integration owner may supply a preconfigured partner sandbox whose runtime capability list can be inspected without invoking a project, recruitment, participant-data, contact, publication, or spend tool; the researcher is never asked to request access or populate platform data.",
|
|
82
82
|
],
|
|
83
|
-
starterPrompt: "Use User Interviews and SomaCheck to help me prepare one clearly named, participant-free test-project plan without changing User Interviews. I am the researcher and I am holding the phone. The study idea is [STUDY IDEA]. Work only from what I provide here. If a product or integration owner has supplied a preconfigured official User Interviews partner sandbox, you may inspect its capability names and schemas, but do not call any platform data or action tool. The planning workflow does not require me to sign up, request access, purchase a plan, or populate User Interviews data. Do not retrieve candidates, participants, screeners, responses, profiles, identifiers, messages, recordings, transcripts, session data, or other workspace data. Propose two neutral study framings and show the exact signal-free project copy. Then offer one short first-person proposition about my own preferred direction and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about another person. Ask what I choose in
|
|
84
|
-
successCondition: "The researcher receives at most one optional signal about their own proposition and
|
|
83
|
+
starterPrompt: "Use User Interviews and SomaCheck to help me prepare one clearly named, participant-free test-project plan without changing User Interviews. I am the researcher and I am holding the phone. The study idea is [STUDY IDEA]. Work only from what I provide here. If a product or integration owner has supplied a preconfigured official User Interviews partner sandbox, you may inspect its capability names and schemas, but do not call any platform data or action tool. The planning workflow does not require me to sign up, request access, purchase a plan, or populate User Interviews data. Do not retrieve candidates, participants, screeners, responses, profiles, identifiers, messages, recordings, transcripts, session data, or other workspace data. Propose two neutral study framings and show the exact signal-free project copy. Then offer one short first-person proposition about my own preferred direction and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about another person. Ask what I choose and accept any explicit response available in this interface. Keep the proposition, reading, confidence, and confirmation out of User Interviews. Return a copy-ready project payload only. Do not create, edit, recruit, invite, message, schedule, screen, launch, publish, attach incentives, spend, read participant data, or call a broader or undocumented tool.",
|
|
84
|
+
successCondition: "The researcher receives at most one optional signal about their own proposition and explicitly indicates their choice; the agent returns a copy-ready signal-free test-project plan, invokes no User Interviews data or action tool, and performs no recruitment, participant read, contact, mutation, launch, publication, incentive, payment, or spend.",
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
87
|
id: "sprig-research-reflection-v1",
|
|
@@ -108,7 +108,7 @@ export const RECIPE_CATALOG = [
|
|
|
108
108
|
"The product or integration owner has provisioned an organization-authorized Great Question connection or partner sandbox at https://greatquestion.co/api/mcp/v1 with PII hiding enabled; running this recipe does not ask the researcher to sign up, upgrade, purchase, administer access, or populate Great Question data.",
|
|
109
109
|
"The owner supplies one participant-free test study, and the client restricts the platform half to get_survey_study for that exact artifact; no discovery or mutation tool is approved.",
|
|
110
110
|
],
|
|
111
|
-
starterPrompt: "Use Great Question and SomaCheck to help me reflect on a five-question test survey plan without changing Great Question. I am the researcher and I am holding the phone. The product or integration owner has provisioned a partner sandbox and named this participant-free test study: [TEST STUDY NAME OR ID]. Read only that study's safe title, purpose, and question structure with get_survey_study. Do not search or list the workspace, and do not read candidates, participants, screeners, responses, sessions, transcripts, recordings, highlights, insights, reels, or other workspace data. Propose two neutral study framings and show their exact questions. Then offer one short first-person proposition about my own preferred framing and wait for my acceptance before any proactive SomaCheck ask. Give the agent the Aligned or Unaligned result plus confidence as context and let it use that context with its judgment. Ask what I choose in
|
|
111
|
+
starterPrompt: "Use Great Question and SomaCheck to help me reflect on a five-question test survey plan without changing Great Question. I am the researcher and I am holding the phone. The product or integration owner has provisioned a partner sandbox and named this participant-free test study: [TEST STUDY NAME OR ID]. Read only that study's safe title, purpose, and question structure with get_survey_study. Do not search or list the workspace, and do not read candidates, participants, screeners, responses, sessions, transcripts, recordings, highlights, insights, reels, or other workspace data. Propose two neutral study framings and show their exact questions. Then offer one short first-person proposition about my own preferred framing and wait for my acceptance before any proactive SomaCheck ask. Give the agent the Aligned or Unaligned result plus confidence as context and let it use that context with its judgment. Ask what I choose and accept any explicit response available in this interface. Keep the proposition, reading, confidence, and my confirmation out of Great Question. Return a signal-free, copy-ready research plan only. Do not create, update, delete, recruit, invite, message, schedule, incentivize, launch, publish, or otherwise write to Great Question. Do not ask me to sign up, upgrade, purchase, administer access, or populate Great Question data.",
|
|
112
112
|
successCondition: "The researcher receives at most one optional signal, states a choice, and receives a copy-ready five-question plan; only get_survey_study reads the exact owner-supplied test artifact, Great Question remains unchanged, and no recruitment or participant data is accessed.",
|
|
113
113
|
},
|
|
114
114
|
{
|
package/dist/server.js
CHANGED
|
@@ -131,9 +131,13 @@ const contextShareSchema = {
|
|
|
131
131
|
const SERVER_INSTRUCTIONS = [
|
|
132
132
|
"SomaCheck lets you ask your person for a vibecheck.",
|
|
133
133
|
"Offer one when useful or when asked.",
|
|
134
|
-
"When asked,
|
|
135
|
-
"Only request_vibecheck creates an immediate phone ask
|
|
134
|
+
"When asked, send a useful statement starting with I or My. Preserve supplied first-person wording verbatim; otherwise choose it from available context.",
|
|
135
|
+
"Only request_vibecheck creates an immediate phone ask, one at a time; use post_vibecheck_statement only when the person asks to stock reflections for later.",
|
|
136
136
|
"Gesture and optional feedback are context, not authorization.",
|
|
137
|
+
"Keep the reading, your interpretation, the person's confirmation, and their choice distinct. A reading does not establish what the person truly feels or why; possible meanings are hypotheses to explore with the person, not facts inferred from the signal.",
|
|
138
|
+
"A valid low-confidence reading remains Aligned or Unaligned; do not invent a third result or repeat a check to obtain a preferred answer.",
|
|
139
|
+
"Report reading and confidence. Agreement or choice is the person's confirmation, never inferred. Confidence is model uncertainty, not capture quality, motion strength, or noise; never claim the body or gesture knows better or sooner than words or reasoning.",
|
|
140
|
+
"When assessing or selecting another person for employment, eligibility, payment, or ranking, do not offer any related vibecheck, including on the user's confidence, readiness, evidence, judgment, or interview performance. Use ordinary discussion only. The user's own career choices remain eligible for self-reflection.",
|
|
137
141
|
"Never infer the SomaCheck identity from the agent login.",
|
|
138
142
|
"Use your judgment.",
|
|
139
143
|
"Never include secrets, raw private content, diagnostic claims, or assess anyone else.",
|
|
@@ -148,8 +152,9 @@ export function createVibecheckServer(dependencies) {
|
|
|
148
152
|
? { capabilities: { experimental: { "claude/channel": {} } } }
|
|
149
153
|
: {}),
|
|
150
154
|
});
|
|
151
|
-
const claudeChannelWatches = new
|
|
155
|
+
const claudeChannelWatches = new Map();
|
|
152
156
|
const claudeChannelNotified = new Set();
|
|
157
|
+
const terminalResultsReadByTool = new Set();
|
|
153
158
|
const startClaudeChannelWatch = (created, token, identity) => {
|
|
154
159
|
if (!supportsClaudeChannel || dependencies.claudeChannelWatch === false)
|
|
155
160
|
return;
|
|
@@ -162,11 +167,17 @@ export function createVibecheckServer(dependencies) {
|
|
|
162
167
|
|| claudeChannelWatches.has(requestId)
|
|
163
168
|
|| claudeChannelNotified.has(requestId))
|
|
164
169
|
return;
|
|
165
|
-
|
|
166
|
-
|
|
170
|
+
const watchAbort = new AbortController();
|
|
171
|
+
claudeChannelWatches.set(requestId, watchAbort);
|
|
172
|
+
void watchForClaudeChannelResult(created, token, identity, dependencies, watchAbort.signal, async (notification) => {
|
|
173
|
+
if (terminalResultsReadByTool.has(requestId) || watchAbort.signal.aborted)
|
|
174
|
+
return;
|
|
167
175
|
claudeChannelNotified.add(requestId);
|
|
168
176
|
await server.server.notification(notification);
|
|
169
|
-
}).finally(() =>
|
|
177
|
+
}).finally(() => {
|
|
178
|
+
claudeChannelWatches.delete(requestId);
|
|
179
|
+
terminalResultsReadByTool.delete(requestId);
|
|
180
|
+
});
|
|
170
181
|
};
|
|
171
182
|
server.registerTool("get_vibecheck_context", {
|
|
172
183
|
title: "Vibecheck Context",
|
|
@@ -197,7 +208,7 @@ export function createVibecheckServer(dependencies) {
|
|
|
197
208
|
});
|
|
198
209
|
server.registerTool("get_vibecheck_status", {
|
|
199
210
|
title: "Vibecheck Status",
|
|
200
|
-
description: "Read the
|
|
211
|
+
description: "Read the SomaCheck database feed before posting. Reports available proposition capacity, when routine replenishment is due, and whether this is the agent's first contact. Database state does not verify phone display.",
|
|
201
212
|
inputSchema: {},
|
|
202
213
|
outputSchema: statusSchema,
|
|
203
214
|
annotations: {
|
|
@@ -255,7 +266,7 @@ export function createVibecheckServer(dependencies) {
|
|
|
255
266
|
});
|
|
256
267
|
server.registerTool("post_vibecheck_statement", {
|
|
257
268
|
title: "Post Vibecheck Statement",
|
|
258
|
-
description: "
|
|
269
|
+
description: "When the person asks to stock reflections for later, or has explicitly authorized scheduled stocking, add one to three optional personalized reflections under Settings → Vibe Checks and return immediately. One can become database-current for Home; the rest stay Up next without extra pushes. This does not verify phone display or delivery. Never call this to add follow-up asks after request_vibecheck. Call get_vibecheck_status first; propositions_needed is the available maximum, not a quota. Submit only genuinely useful statements and never invent extras to fill capacity. A still-active scheduled authorization does not require repeated consent each run.",
|
|
259
270
|
inputSchema: {
|
|
260
271
|
statements: z.array(z.string().min(1)).min(1).max(3)
|
|
261
272
|
.describe("Distinct personalized statements for this person to test, ordered most useful first."),
|
|
@@ -276,14 +287,14 @@ export function createVibecheckServer(dependencies) {
|
|
|
276
287
|
return {
|
|
277
288
|
content: [{
|
|
278
289
|
type: "text",
|
|
279
|
-
text: `Added ${created.length} under Settings → Vibe Checks: ${presented} current, ${queued}
|
|
290
|
+
text: `Added ${created.length} under Settings → Vibe Checks: ${presented} database-current, ${queued} queued. This is asynchronous feed inventory, not verified phone display or an immediate request.`,
|
|
280
291
|
}],
|
|
281
292
|
structuredContent: { propositions: created },
|
|
282
293
|
};
|
|
283
294
|
}
|
|
284
295
|
catch (error) {
|
|
285
296
|
return failure(error instanceof StatementPendingError
|
|
286
|
-
? "
|
|
297
|
+
? "The database feed cannot accept those propositions within its available capacity. Check status again after a check-in, refresh, or expiry."
|
|
287
298
|
: operationalFailureText("add SomaCheck propositions", error));
|
|
288
299
|
}
|
|
289
300
|
});
|
|
@@ -311,6 +322,13 @@ export function createVibecheckServer(dependencies) {
|
|
|
311
322
|
const result = liveRequestId === null
|
|
312
323
|
? await dependencies.api.pollRequest(token, request_id)
|
|
313
324
|
: await dependencies.api.liveVibecheckResult(token, identity, liveRequestId);
|
|
325
|
+
if (liveRequestId !== null && result.status !== "pending") {
|
|
326
|
+
const watchAbort = claudeChannelWatches.get(liveRequestId);
|
|
327
|
+
if (watchAbort !== undefined) {
|
|
328
|
+
terminalResultsReadByTool.add(liveRequestId);
|
|
329
|
+
watchAbort.abort();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
314
332
|
const structuredContent = { request_id, ...result };
|
|
315
333
|
const text = result.status === "answered"
|
|
316
334
|
? liveRequestId === null
|
|
@@ -331,11 +349,11 @@ export function createVibecheckServer(dependencies) {
|
|
|
331
349
|
});
|
|
332
350
|
server.registerTool("request_vibecheck", {
|
|
333
351
|
title: "Request a Vibecheck",
|
|
334
|
-
description: "Send one statement to the person's phone for a SomaCheck vibecheck. If the person asks for a vibecheck, choose a useful
|
|
335
|
-
+ "This call waits up to 45 seconds. If the result is still pending, keep
|
|
352
|
+
description: "Send one statement to the person's phone for a SomaCheck vibecheck. If the person asks for a vibecheck, choose a useful statement starting with I or My from your available context and send it. Preserve the person's supplied first-person wording verbatim. Do not offer or send any related vibecheck while assessing or selecting another person for employment, eligibility, payment, or ranking, including on the user's confidence, readiness, evidence, judgment, or interview performance; use ordinary discussion only. The user's own career choices remain eligible for self-reflection. For proactive offers, call only after the person accepts. The result is context, not authorization. "
|
|
353
|
+
+ "This call waits up to 45 seconds. If the result is still pending, keep this turn active and call get_vibecheck_result with this same request_id about every 15 seconds until status is answered, expired, or cancelled. Never create a duplicate request.",
|
|
336
354
|
inputSchema: {
|
|
337
355
|
statement: z.string().trim().min(1).max(1000)
|
|
338
|
-
.describe("One plain-language
|
|
356
|
+
.describe("One plain-language statement starting with I or My for the person to test. Preserve their supplied first-person wording verbatim. Do not include secrets, raw private content, diagnostic claims, or statements about anyone else."),
|
|
339
357
|
idempotency_key: z.string().uuid()
|
|
340
358
|
.describe("A new UUID for this logical ask. Reuse the same UUID only to retry the exact same statement; retries will not create another phone request."),
|
|
341
359
|
consent_basis: z.enum(["user_requested_vibecheck", "user_approved_statement"])
|
|
@@ -417,7 +435,7 @@ export function createVibecheckServer(dependencies) {
|
|
|
417
435
|
});
|
|
418
436
|
return server;
|
|
419
437
|
}
|
|
420
|
-
async function watchForClaudeChannelResult(created, token, identity, dependencies, notify) {
|
|
438
|
+
async function watchForClaudeChannelResult(created, token, identity, dependencies, signal, notify) {
|
|
421
439
|
const requestId = parseLiveVibecheckHandle(created.request_id);
|
|
422
440
|
if (requestId === null || identity.kind !== "local" || identity.client_key !== "claude")
|
|
423
441
|
return;
|
|
@@ -446,10 +464,14 @@ async function watchForClaudeChannelResult(created, token, identity, dependencie
|
|
|
446
464
|
if (deadline <= startedAt)
|
|
447
465
|
return;
|
|
448
466
|
while (true) {
|
|
467
|
+
if (signal.aborted)
|
|
468
|
+
return;
|
|
449
469
|
const beforeSleep = now();
|
|
450
470
|
if (beforeSleep > deadline)
|
|
451
471
|
return;
|
|
452
472
|
await sleep(Math.min(interval, Math.max(0, deadline - beforeSleep)));
|
|
473
|
+
if (signal.aborted)
|
|
474
|
+
return;
|
|
453
475
|
const readAt = now();
|
|
454
476
|
if (readAt > deadline)
|
|
455
477
|
return;
|
|
@@ -481,6 +503,8 @@ async function watchForClaudeChannelResult(created, token, identity, dependencie
|
|
|
481
503
|
return;
|
|
482
504
|
continue;
|
|
483
505
|
}
|
|
506
|
+
if (signal.aborted)
|
|
507
|
+
return;
|
|
484
508
|
const handle = `live:${requestId}`;
|
|
485
509
|
const content = lifecycle.status === "answered"
|
|
486
510
|
? `SomaCheck vibecheck ${handle} completed: ${lifecycle.verdict}, confidence ${formatChannelConfidence(lifecycle.confidence)}${formatUserFeedback(lifecycle.user_feedback)}.`
|
|
@@ -534,22 +558,21 @@ function formatUserFeedback(feedback) {
|
|
|
534
558
|
/** Text for a still-pending Live Ask, whether just created (delivery not
|
|
535
559
|
* failed/skipped) or re-read via get_vibecheck_result. `expiresAt` is null
|
|
536
560
|
* when the caller has no expiry to report (get_vibecheck_result's live read
|
|
537
|
-
* does not receive one). `
|
|
538
|
-
* server when
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
return `Vibecheck ${requestId} is pending. It expires at ${expiresAt}. This session will be notified automatically when the person responds.`;
|
|
547
|
-
}
|
|
561
|
+
* does not receive one). `hasChannelWatch` is true only for the local stdio
|
|
562
|
+
* server when its Claude Channel watcher is running. A running watcher proves
|
|
563
|
+
* only that the server will attempt a notification; it cannot prove that the
|
|
564
|
+
* host enabled or is listening to the experimental Channel. The stable-handle
|
|
565
|
+
* polling fallback therefore remains explicit in both modes. */
|
|
566
|
+
function pendingWaitText(requestId, expiresAt, hasChannelWatch) {
|
|
567
|
+
const channelNotice = hasChannelWatch
|
|
568
|
+
? "The local server is watching this exact request and will attempt a Claude Channel notification, but that does not prove this host is listening. "
|
|
569
|
+
: "";
|
|
548
570
|
return `Vibecheck ${requestId} is pending. SomaCheck has not received a response yet. `
|
|
549
571
|
+ `If no phone prompt appears, open SomaCheck on the same account; phone setup is at ${SOMACHECK_SETUP_URL}. `
|
|
572
|
+
+ channelNotice
|
|
550
573
|
+ `Call get_vibecheck_result with request_id ${requestId} again in about 15 seconds, `
|
|
551
|
-
+ `and keep polling
|
|
552
|
-
+ `Do not end your turn or
|
|
574
|
+
+ `and keep this turn active while polling only that request until the state is answered, expired, or cancelled. `
|
|
575
|
+
+ `Do not call request_vibecheck again, end your turn, or treat a gesture as authorization.`
|
|
553
576
|
+ (expiresAt === null ? "" : ` It expires at ${expiresAt}.`);
|
|
554
577
|
}
|
|
555
578
|
async function waitForLiveVibecheck(created, token, identity, dependencies, signal, deadline, progress) {
|
|
@@ -615,16 +638,19 @@ async function waitForLiveVibecheck(created, token, identity, dependencies, sign
|
|
|
615
638
|
}
|
|
616
639
|
function summarise(status) {
|
|
617
640
|
const cadence = status.cadence;
|
|
641
|
+
if (status.propositions_needed <= 0) {
|
|
642
|
+
return `This connection's database feed has no available slots; ${status.queued_proposition_count} propositions are queued. Do not post another feed item. This status does not verify phone display. Routine replenishment uses a ${formatDuration(cadence.followup_within_seconds)} floor.`;
|
|
643
|
+
}
|
|
618
644
|
if (status.first_run_intro.should_offer_now) {
|
|
619
|
-
return `This is your first contact. Introduce the SomaCheck ritual,
|
|
645
|
+
return `This is your first contact. Introduce the SomaCheck ritual. The feed has up to ${status.propositions_needed} available slot${status.propositions_needed === 1 ? "" : "s"}; only if the person asks to stock reflections for later or has explicitly authorized scheduled stocking, add 1 to ${status.propositions_needed} genuinely useful proposition${status.propositions_needed === 1 ? "" : "s"}. Never invent extras to fill capacity.`;
|
|
620
646
|
}
|
|
621
647
|
if (status.propositions_needed > 0) {
|
|
622
648
|
const requested = status.replenishment_requested_at === null
|
|
623
649
|
? ""
|
|
624
650
|
: ` The person requested replenishment at ${status.replenishment_requested_at}.`;
|
|
625
|
-
return `The
|
|
651
|
+
return `The database feed has ${status.pending_proposition_count} of 3 propositions and up to ${status.propositions_needed} available slot${status.propositions_needed === 1 ? "" : "s"}. Only if the person asks to stock reflections for later or has explicitly authorized scheduled stocking, add 1 to ${status.propositions_needed} genuinely useful proposition${status.propositions_needed === 1 ? "" : "s"}; never invent extras to fill capacity. A still-active scheduled authorization does not require repeated consent each run. This status does not verify phone display.${requested}`;
|
|
626
652
|
}
|
|
627
|
-
return
|
|
653
|
+
return "Feed capacity is unavailable. Do not post another feed item until status can be confirmed.";
|
|
628
654
|
}
|
|
629
655
|
function formatDuration(seconds) {
|
|
630
656
|
const hours = seconds / 3600;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@somacheck/vibecheck",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"mcpName": "io.github.Sensie-agents/vibecheck",
|
|
5
5
|
"description": "Body language for AI agents, on your terms. A consented SomaCheck signal for how a thought or choice lands.",
|
|
6
6
|
"repository": {
|
|
@@ -77,8 +77,8 @@ or `search_observations` (observation identifiers and representative verbatim
|
|
|
77
77
|
snippets), and never surfaces individual feedback, source quotes, respondent
|
|
78
78
|
identifiers, or free text. The agent offers two defensible interpretations of
|
|
79
79
|
what the aggregate signal suggests, then one short first-person proposition
|
|
80
|
-
about the researcher's own interpretation or next step. After the researcher
|
|
81
|
-
|
|
80
|
+
about the researcher's own interpretation or next step. After the researcher
|
|
81
|
+
explicitly indicates a choice, the agent stops. There is no Chattermill write.
|
|
82
82
|
|
|
83
83
|
## Starter prompt
|
|
84
84
|
|
|
@@ -98,7 +98,8 @@ aggregate signal suggests, with the tradeoff for each. Then offer one short
|
|
|
98
98
|
first-person proposition about my own interpretation or next step and wait
|
|
99
99
|
for my acceptance before any proactive SomaCheck ask. Treat Aligned or
|
|
100
100
|
Unaligned plus confidence as context, not truth, diagnosis, authorization, or
|
|
101
|
-
evidence about any individual customer. Ask what I choose
|
|
101
|
+
evidence about any individual customer. Ask what I choose and accept any
|
|
102
|
+
explicit response available in this interface. Keep the
|
|
102
103
|
proposition, reading, confidence, and my confirmation out of Chattermill. Do
|
|
103
104
|
not write to Chattermill; the hosted MCP is read-only. If the preconfigured
|
|
104
105
|
connection, mcp:read, or a safe aggregate tool is absent, return the copy-ready
|
|
@@ -198,9 +199,9 @@ recipe work. If the runtime does not expose `get_metrics` or
|
|
|
198
199
|
researcher decides). `unaligned` may indicate possible inner conflict
|
|
199
200
|
relative to the proposition; it does not name a cause, choose an
|
|
200
201
|
interpretation, or justify a research claim.
|
|
201
|
-
11. **
|
|
202
|
-
whether they want a third option, or whether they want to stop.
|
|
203
|
-
their
|
|
202
|
+
11. **Return authority.** Ask the researcher which interpretation they choose,
|
|
203
|
+
whether they want a third option, or whether they want to stop. Accept any
|
|
204
|
+
explicit response available in the interface and follow their choice.
|
|
204
205
|
12. **Keep the signal out of Chattermill.** Do not call any write, mutation,
|
|
205
206
|
export, tag, theme, highlight, insight, or analytics tool. Do not store
|
|
206
207
|
the proposition, reading, confidence, confirmation, or gesture metadata
|
|
@@ -246,8 +247,8 @@ The test passes when:
|
|
|
246
247
|
- the researcher receives at most one optional SomaCheck check-in on their
|
|
247
248
|
phone on an exact first-person proposition about their own interpretation or
|
|
248
249
|
next step;
|
|
249
|
-
- the agent presents the result as context, asks the researcher to
|
|
250
|
-
choice
|
|
250
|
+
- the agent presents the result as context, asks the researcher to indicate
|
|
251
|
+
their choice explicitly, and follows that choice;
|
|
251
252
|
- the agent makes no Chattermill write, mutation, export, share, tag,
|
|
252
253
|
comment, or analytics call; and
|
|
253
254
|
- no individual customer, respondent, or employee data enters the cross-MCP
|
|
@@ -271,7 +272,7 @@ The test passes when:
|
|
|
271
272
|
then proceed without a reading if still unresolved.
|
|
272
273
|
- **Unreadable capture:** Offer a retry only if the researcher wants it;
|
|
273
274
|
unreadable is not a third interpretation.
|
|
274
|
-
- **Researcher disagrees with the reading:** Follow the researcher's
|
|
275
|
+
- **Researcher disagrees with the reading:** Follow the researcher's explicit
|
|
275
276
|
choice without reconciliation or repetition.
|
|
276
277
|
|
|
277
278
|
## Privacy boundary
|
|
@@ -306,7 +307,7 @@ The test passes when:
|
|
|
306
307
|
- [ ] The proposition is first-person and contains no Chattermill content.
|
|
307
308
|
- [ ] At most one SomaCheck request is created for the choice.
|
|
308
309
|
- [ ] Observation, interpretation, confirmation, and choice remain separate.
|
|
309
|
-
- [ ] The researcher
|
|
310
|
+
- [ ] The researcher explicitly indicates a choice and the agent follows it.
|
|
310
311
|
- [ ] The agent makes no Chattermill write, mutation, export, share, tag,
|
|
311
312
|
comment, or analytics call.
|
|
312
313
|
- [ ] No individual customer, respondent, or employee data enters the
|
|
@@ -115,7 +115,7 @@ makes the reading an automatic write condition.
|
|
|
115
115
|
`pending`, is `expired` or `cancelled`, or errors, continue without a result;
|
|
116
116
|
do not infer one or start another request.
|
|
117
117
|
8. **Return authority.** Offer the options to revise, investigate, proceed,
|
|
118
|
-
pause, or leave the artifact unchanged.
|
|
118
|
+
pause, or leave the artifact unchanged. An explicit researcher choice overrides
|
|
119
119
|
the signal.
|
|
120
120
|
9. **Keep the signal private.** Do not write the verdict, confidence, gesture,
|
|
121
121
|
or confirmation to Dovetail. If the researcher asks to record a next step,
|
|
@@ -153,7 +153,7 @@ Do not trigger when:
|
|
|
153
153
|
- the task is ordinary Dovetail retrieval, summarization, tagging, or export;
|
|
154
154
|
- the proposed subject is anyone other than the researcher;
|
|
155
155
|
- the source contains raw or identifiable participant material;
|
|
156
|
-
- the researcher has already made a clear
|
|
156
|
+
- the researcher has already made a clear choice;
|
|
157
157
|
- the result would determine inclusion, quality, compensation, performance, or
|
|
158
158
|
another consequential outcome; or
|
|
159
159
|
- a vibecheck was already used for the same decision.
|
|
@@ -48,7 +48,8 @@ neutral study framings and show their exact questions. Then offer one short
|
|
|
48
48
|
first-person proposition about my own preferred framing and wait for my
|
|
49
49
|
acceptance before any proactive SomaCheck ask. Give the agent the Aligned or
|
|
50
50
|
Unaligned result plus confidence as context and let it use that context with
|
|
51
|
-
its judgment. Ask what I choose
|
|
51
|
+
its judgment. Ask what I choose and accept any explicit response available in
|
|
52
|
+
this interface. Keep the proposition, reading,
|
|
52
53
|
confidence, and my confirmation out of Great Question. Return a signal-free,
|
|
53
54
|
copy-ready research plan only. Do not create, update, delete, recruit, invite,
|
|
54
55
|
message, schedule, incentivize, launch, publish, or otherwise write to Great
|
|
@@ -119,8 +120,8 @@ owner-supplied artifact.
|
|
|
119
120
|
or Unaligned reading, and confidence. Let it combine that context with the
|
|
120
121
|
conversation and its judgment. Keep observation, interpretation,
|
|
121
122
|
confirmation, and choice distinct.
|
|
122
|
-
9. **Ask the researcher to
|
|
123
|
-
follows and may differ from the signal.
|
|
123
|
+
9. **Return authority.** Ask the researcher to indicate their choice explicitly.
|
|
124
|
+
Their choice controls what follows and may differ from the signal.
|
|
124
125
|
10. **Return a copy-ready plan.** Include only a test title, goal/purpose,
|
|
125
126
|
language, and the five questions. Do not attach an incentive, consent form,
|
|
126
127
|
screener, candidates, recruitment settings, or send settings.
|
|
@@ -169,7 +170,7 @@ The end-to-end test passes only when:
|
|
|
169
170
|
- **SomaCheck unresolved:** Use the same handle once later, then proceed without
|
|
170
171
|
a reading if unresolved.
|
|
171
172
|
- **Unreadable capture:** Offer a retry only if the researcher wants it.
|
|
172
|
-
- **The researcher's
|
|
173
|
+
- **The researcher's choice differs from the reading:** Follow their explicit choice
|
|
173
174
|
without reconciliation or repetition.
|
|
174
175
|
|
|
175
176
|
## Privacy boundary
|
|
@@ -73,7 +73,7 @@ summary (mission completion rates, time on task, success-rate aggregate,
|
|
|
73
73
|
summary counts). It does not open transcripts, response rows, participant
|
|
74
74
|
identifiers, recordings, or free-text fields. The agent offers two defensible
|
|
75
75
|
interpretation framings and one short first-person proposition about the
|
|
76
|
-
researcher's own interpretation plan. After the researcher
|
|
76
|
+
researcher's own interpretation plan. After the researcher explicitly indicates a choice,
|
|
77
77
|
the agent stops. There is no Maze write.
|
|
78
78
|
|
|
79
79
|
## Starter prompt
|
|
@@ -94,7 +94,8 @@ defensible interpretation framings. Then offer one short first-person
|
|
|
94
94
|
proposition about my own interpretation plan and wait for my acceptance
|
|
95
95
|
before any proactive SomaCheck ask. Treat Aligned or Unaligned plus
|
|
96
96
|
confidence as context, not truth, diagnosis, authorization, or evidence
|
|
97
|
-
about a Maze participant. Ask what I choose
|
|
97
|
+
about a Maze participant. Ask what I choose and accept any explicit response
|
|
98
|
+
available in this interface. Keep the
|
|
98
99
|
proposition, reading, confidence, and my confirmation out of Maze. Do
|
|
99
100
|
not create, edit, publish, delete, archive, export, share, tag, comment,
|
|
100
101
|
or write to Maze, a hidden field, a webhook, or any analytics record.
|
|
@@ -192,8 +193,8 @@ read, label the Maze half untested and stop.
|
|
|
192
193
|
decides). `unaligned` may indicate possible inner conflict relative
|
|
193
194
|
to the proposition; it does not name a cause, choose an interpretation,
|
|
194
195
|
or justify a research claim.
|
|
195
|
-
11. **
|
|
196
|
-
want a third option, or whether they want to stop. Follow their
|
|
196
|
+
11. **Return authority.** Ask the researcher which framing they choose, whether they
|
|
197
|
+
want a third option, or whether they want to stop. Follow their explicit
|
|
197
198
|
choice.
|
|
198
199
|
12. **Keep the signal out of Maze.** Do not call any Maze write, mutation,
|
|
199
200
|
export, webhook, comment, tag, highlight, insight, analytics, or
|
|
@@ -241,8 +242,8 @@ The test passes when:
|
|
|
241
242
|
theme, highlight, insight, automation, or write tool;
|
|
242
243
|
- the researcher receives at most one optional SomaCheck check-in on their phone
|
|
243
244
|
on an exact first-person proposition about their own interpretation plan;
|
|
244
|
-
- the agent presents the result as context, asks the researcher to
|
|
245
|
-
choice
|
|
245
|
+
- the agent presents the result as context, asks the researcher to indicate
|
|
246
|
+
their choice explicitly, and follows that choice;
|
|
246
247
|
- the agent makes no Maze write, mutation, export, share, tag,
|
|
247
248
|
comment, or analytics call; and
|
|
248
249
|
- no Maze participant, respondent, or employee data enters the
|
|
@@ -271,7 +272,7 @@ The test passes when:
|
|
|
271
272
|
later, then proceed without a reading if still unresolved.
|
|
272
273
|
- **Unreadable capture:** Offer a retry only if the researcher wants it;
|
|
273
274
|
unreadable is not a third interpretation.
|
|
274
|
-
- **Researcher disagrees with the reading:** Follow the researcher's
|
|
275
|
+
- **Researcher disagrees with the reading:** Follow the researcher's explicit choice
|
|
275
276
|
without reconciliation or repetition.
|
|
276
277
|
|
|
277
278
|
## Privacy boundary
|
|
@@ -308,8 +309,7 @@ The test passes when:
|
|
|
308
309
|
- [ ] At most one SomaCheck request is created for the choice.
|
|
309
310
|
- [ ] Observation, interpretation, confirmation, and choice remain
|
|
310
311
|
separate.
|
|
311
|
-
- [ ] The researcher
|
|
312
|
-
choice.
|
|
312
|
+
- [ ] The researcher explicitly indicates a choice and the agent follows it.
|
|
313
313
|
- [ ] The agent makes no Maze mutation, write, export, share, tag,
|
|
314
314
|
comment, or analytics call.
|
|
315
315
|
- [ ] No Maze participant, respondent, or employee data enters the
|
|
@@ -124,7 +124,7 @@ automatic decision gate.
|
|
|
124
124
|
proceed to separate review, pause, or leave unchanged. Do not call
|
|
125
125
|
`create_filter_set`, `create_study`, or `publish_study`. If the researcher
|
|
126
126
|
chooses a change, produce a reviewable draft outside Prolific; platform
|
|
127
|
-
mutation is a new action requiring explicit instruction.
|
|
127
|
+
mutation is a new action requiring explicit instruction. An explicit researcher
|
|
128
128
|
choice overrides the signal.
|
|
129
129
|
10. **Keep the signal private.** Do not write the verdict, confidence, gesture,
|
|
130
130
|
confirmation, or inferred meaning to Prolific or another research platform.
|
|
@@ -161,7 +161,7 @@ Do not trigger when:
|
|
|
161
161
|
- the proposed subject is a participant, employee, cohort, or respondent;
|
|
162
162
|
- the result would affect eligibility, filtering, payment, bonus, rejection,
|
|
163
163
|
submission quality, authenticity, or performance;
|
|
164
|
-
- the researcher has already made a clear
|
|
164
|
+
- the researcher has already made a clear choice;
|
|
165
165
|
- the agent is being asked to publish, gate, or automate a launch; or
|
|
166
166
|
- a vibecheck was already used for the same decision.
|
|
167
167
|
|
|
@@ -26,7 +26,8 @@ about a respondent, or a research decision. The researcher remains the authority
|
|
|
26
26
|
|
|
27
27
|
The researcher supplies a participant-free survey goal. The agent drafts two
|
|
28
28
|
four-question versions and may offer one SomaCheck check-in on the researcher's
|
|
29
|
-
own preferred direction. The researcher then
|
|
29
|
+
own preferred direction. The researcher then explicitly indicates a choice.
|
|
30
|
+
The output is a
|
|
30
31
|
signal-free survey definition for a QuestionPro owner to review. This recipe
|
|
31
32
|
does not create, publish, distribute, or populate a survey.
|
|
32
33
|
|
|
@@ -43,7 +44,8 @@ upgrade, buy a plan, administer access, or populate QuestionPro data. Propose tw
|
|
|
43
44
|
questionnaire framings and show the exact questions. Then offer one short
|
|
44
45
|
first-person proposition about my own preferred direction and wait for my
|
|
45
46
|
acceptance before any proactive SomaCheck ask. Give the result and confidence to
|
|
46
|
-
the agent as context and let it use its judgment. Ask what I choose
|
|
47
|
+
the agent as context and let it use its judgment. Ask what I choose and accept
|
|
48
|
+
any explicit response available in this interface.
|
|
47
49
|
Keep the proposition, reading, confidence, and confirmation out of QuestionPro.
|
|
48
50
|
Return a copy-ready, signal-free survey definition only. Do not create, edit,
|
|
49
51
|
send, distribute, publish, recruit, launch, access responses, or spend anything.
|
|
@@ -77,7 +79,8 @@ send, distribute, publish, recruit, launch, access responses, or spend anything.
|
|
|
77
79
|
6. Give the proposition, Aligned or Unaligned result, and confidence to the
|
|
78
80
|
agent. Let the agent use its judgment in context without treating the result
|
|
79
81
|
as authorization or a claim about respondents.
|
|
80
|
-
7. Ask
|
|
82
|
+
7. Ask the researcher to indicate their choice explicitly. Their choice controls
|
|
83
|
+
the plan.
|
|
81
84
|
8. Return a copy-ready payload with title, purpose, questions, answer choices,
|
|
82
85
|
and optional logic. Exclude all SomaCheck data and platform identifiers.
|
|
83
86
|
9. Stop before any QuestionPro data or action call. A partner owner may review
|
|
@@ -115,8 +115,8 @@ Typeform write or launch condition.
|
|
|
115
115
|
`pending`, is `expired` or `cancelled`, or errors, continue without a result;
|
|
116
116
|
do not infer one or start another request.
|
|
117
117
|
8. **Return authority.** Offer revise, split a question, soften leading
|
|
118
|
-
wording, add an answer option, pilot, proceed, pause, or leave unchanged.
|
|
119
|
-
|
|
118
|
+
wording, add an answer option, pilot, proceed, pause, or leave unchanged. An
|
|
119
|
+
explicit researcher choice overrides the signal.
|
|
120
120
|
9. **Keep the signal private.** Do not write the verdict, confidence, gesture,
|
|
121
121
|
or confirmation to Typeform. If the researcher asks for a Typeform edit,
|
|
122
122
|
show the exact signal-free edit first and call the Typeform write tool only
|
|
@@ -159,7 +159,7 @@ Do not trigger when:
|
|
|
159
159
|
free-text answers;
|
|
160
160
|
- the result would affect eligibility, payment, employment, grading, access,
|
|
161
161
|
support priority, response quality, or survey validity;
|
|
162
|
-
- the researcher has already made a clear
|
|
162
|
+
- the researcher has already made a clear choice;
|
|
163
163
|
- the researcher has declined a recent offer or opted out; or
|
|
164
164
|
- a vibecheck was already used for the same decision.
|
|
165
165
|
|
|
@@ -57,7 +57,8 @@ gates.
|
|
|
57
57
|
|
|
58
58
|
The researcher gives the agent a participant-free study idea. The agent drafts
|
|
59
59
|
two neutral framings, offers one first-person SomaCheck check-in about the
|
|
60
|
-
researcher's own direction, and
|
|
60
|
+
researcher's own direction, and accepts any explicit response available in the
|
|
61
|
+
interface. The agent
|
|
61
62
|
returns a complete copy-ready payload and stops. User Interviews remains
|
|
62
63
|
unchanged. Any later draft creation is a separate future recipe and review, not
|
|
63
64
|
an optional branch of this one.
|
|
@@ -79,7 +80,8 @@ Propose two neutral study framings and show the exact
|
|
|
79
80
|
signal-free project copy. Then offer one short first-person proposition about
|
|
80
81
|
my own preferred direction and ask for one SomaCheck check-in on that exact
|
|
81
82
|
wording. Keep the proposition, reading, confidence, and my confirmation out of
|
|
82
|
-
User Interviews. Afterward ask what I choose
|
|
83
|
+
User Interviews. Afterward ask what I choose and accept any explicit response
|
|
84
|
+
available in this interface. Return the complete
|
|
83
85
|
signal-free, copy-ready project payload only. Do not create, edit, recruit,
|
|
84
86
|
invite, message, schedule, screen, launch, publish, attach incentives, spend,
|
|
85
87
|
read participant data, or call a broader or undocumented tool.
|
|
@@ -152,14 +154,14 @@ tools, stop without calling it.
|
|
|
152
154
|
8. **Return authority.** Separate observation, interpretation (`aligned` or
|
|
153
155
|
`unaligned` plus confidence), confirmation, and choice. `unaligned` may
|
|
154
156
|
indicate possible inner conflict relative to the proposition; it does not
|
|
155
|
-
identify a cause or select a study design. The researcher's
|
|
157
|
+
identify a cause or select a study design. The researcher's explicit choice
|
|
156
158
|
controls.
|
|
157
159
|
9. **Prepare the exact payload.** Show title, purpose, study type, questions or
|
|
158
160
|
tasks, and any required non-contact fields. Exclude the proposition, result,
|
|
159
161
|
confidence, confirmation, SomaCheck wording, participant metadata, and
|
|
160
162
|
hidden fields.
|
|
161
163
|
10. **Stop before every platform call.** The SomaCheck reading and the
|
|
162
|
-
researcher's
|
|
164
|
+
researcher's explicit choice are not approval to use User Interviews. Do not
|
|
163
165
|
call create, update,
|
|
164
166
|
read-back, recruitment, messaging, scheduling, participant, incentive,
|
|
165
167
|
launch, publish, or data tools.
|
|
@@ -188,8 +190,8 @@ Not allowed:
|
|
|
188
190
|
The test passes when:
|
|
189
191
|
|
|
190
192
|
- the researcher receives at most one live SomaCheck request on their phone;
|
|
191
|
-
- the agent presents the result as context and asks the researcher
|
|
192
|
-
|
|
193
|
+
- the agent presents the result as context and asks the researcher to indicate
|
|
194
|
+
their choice explicitly;
|
|
193
195
|
- the agent returns the exact signal-free, copy-ready project payload;
|
|
194
196
|
- no User Interviews data or action tool is invoked and the workspace remains
|
|
195
197
|
unchanged; and
|
|
@@ -212,7 +214,7 @@ The test passes when:
|
|
|
212
214
|
proceed without a reading if unresolved.
|
|
213
215
|
- **Unreadable capture:** Offer a retry only if the researcher wants it;
|
|
214
216
|
unreadable is not a third interpretation.
|
|
215
|
-
- **Researcher disagrees with the reading:** Follow the researcher's
|
|
217
|
+
- **Researcher disagrees with the reading:** Follow the researcher's explicit
|
|
216
218
|
choice without reconciliation or repetition.
|
|
217
219
|
|
|
218
220
|
## Privacy boundary
|