@raidiant/notifai 11.6.0 → 11.6.1-beta.3

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +12 -14
  3. package/dist/codex-tool-messages.d.ts +1 -12
  4. package/dist/codex-tool-messages.js +20 -66
  5. package/dist/codex-tool-messages.js.map +1 -1
  6. package/dist/codex-wake.d.ts +6 -25
  7. package/dist/codex-wake.js +6 -25
  8. package/dist/codex-wake.js.map +1 -1
  9. package/dist/commands-ask.d.ts +2 -3
  10. package/dist/commands-ask.js +29 -11
  11. package/dist/commands-ask.js.map +1 -1
  12. package/dist/commands-core.d.ts +1 -1
  13. package/dist/commands-hook-attend.js +39 -53
  14. package/dist/commands-hook-attend.js.map +1 -1
  15. package/dist/commands-hook-run.js +50 -12
  16. package/dist/commands-hook-run.js.map +1 -1
  17. package/dist/commands-receive.d.ts +3 -0
  18. package/dist/commands-receive.js +55 -0
  19. package/dist/commands-receive.js.map +1 -0
  20. package/dist/commands-send.js +1 -1
  21. package/dist/commands-send.js.map +1 -1
  22. package/dist/commands-update-check.js +2 -1
  23. package/dist/commands-update-check.js.map +1 -1
  24. package/dist/commands.d.ts +1 -0
  25. package/dist/commands.js +1 -0
  26. package/dist/commands.js.map +1 -1
  27. package/dist/config-schema.js +2 -2
  28. package/dist/config-schema.js.map +1 -1
  29. package/dist/hook-acknowledgements.js +7 -1
  30. package/dist/hook-acknowledgements.js.map +1 -1
  31. package/dist/hook-gates.d.ts +1 -1
  32. package/dist/hook-gates.js +0 -1
  33. package/dist/hook-gates.js.map +1 -1
  34. package/dist/hook-lifecycle.d.ts +2 -0
  35. package/dist/hook-lifecycle.js +354 -360
  36. package/dist/hook-lifecycle.js.map +1 -1
  37. package/dist/hook-question-lock.js +3 -3
  38. package/dist/hook-question-lock.js.map +1 -1
  39. package/dist/hook-types.d.ts +15 -7
  40. package/dist/logging.js +1 -1
  41. package/dist/logging.js.map +1 -1
  42. package/dist/program.d.ts +2 -1
  43. package/dist/program.js +11 -6
  44. package/dist/program.js.map +1 -1
  45. package/dist/question-settlement-process.d.ts +5 -3
  46. package/dist/question-settlement-process.js +4 -4
  47. package/dist/question-settlement-process.js.map +1 -1
  48. package/dist/session-attendant-probe.d.ts +1 -1
  49. package/dist/session-attendant-probe.js +1 -1
  50. package/dist/session-attendant-state.d.ts +3 -3
  51. package/dist/session-attendant-state.js +3 -3
  52. package/dist/session-attendant.d.ts +2 -0
  53. package/dist/session-attendant.js +16 -1
  54. package/dist/session-attendant.js.map +1 -1
  55. package/dist/session-delivery.d.ts +5 -1
  56. package/dist/session-delivery.js +10 -0
  57. package/dist/session-delivery.js.map +1 -1
  58. package/dist/session-inputs.d.ts +22 -0
  59. package/dist/session-inputs.js +254 -0
  60. package/dist/session-inputs.js.map +1 -0
  61. package/dist/session-message-handoff.js +6 -1
  62. package/dist/session-message-handoff.js.map +1 -1
  63. package/dist/skill-source/manifest.json +6 -6
  64. package/dist/skill-source/notifai/SKILL.md +20 -21
  65. package/dist/skill-source/notifai/references/diagnostics.md +1 -1
  66. package/dist/skill-source/notifai/references/harness-setup.md +39 -33
  67. package/dist/skill-source/notifai/references/notes-and-edits.md +6 -1
  68. package/package.json +2 -2
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Native queues carry a wake, never User words. The foreground consumer reads
3
+ * the current pending inputs and claims one bounded batch immediately before
4
+ * presentation. A late wake therefore cannot resurrect an acknowledged answer.
5
+ */
6
+ import { randomUUID } from 'node:crypto';
7
+ import { readFileSync } from 'node:fs';
8
+ import path from 'node:path';
9
+ import { atomicWriteFileSync } from './atomic-file.js';
10
+ import { sanitizeSessionId, stateDir } from './config.js';
11
+ import { answersContext, clearAcknowledgementObligation, recordMessageAcknowledgementDue } from './hook-acknowledgements.js';
12
+ import { retiringQuestion } from './hook-question-retirement.js';
13
+ import { readSessionIncarnation, readSessionState, recordSessionNotified, sessionHasEnded, updateSessionState } from './hook-session-state.js';
14
+ import { sessionMessageContext } from './injection-render.js';
15
+ import { currentProcessIdentity, processIdentityLiveness } from './process-identity.js';
16
+ import { answerWriterGone, beginHandOff, readDeliveryJournal } from './session-delivery.js';
17
+ export function sessionInputWake() {
18
+ return `Notifai — user input may be waiting for this session. Run \`notifai receive\` before continuing. If no input remains, continue your work. This wake-up contains no note, answer, or approval.`;
19
+ }
20
+ /** Atomically coalesce native wakes until one actually reaches its consumer. */
21
+ export async function wakeSessionInputs(sessionId, env, send, log) {
22
+ const incarnation = readSessionIncarnation(sessionId, env)?.incarnation ?? `session:${sessionId}`;
23
+ const writer = currentProcessIdentity();
24
+ if (writer === null || sessionHasEnded(sessionId, env))
25
+ return;
26
+ const token = randomUUID();
27
+ let elected = false;
28
+ updateSessionState(sessionId, env, (state) => {
29
+ if (state.input_wake?.incarnation === incarnation &&
30
+ (state.input_wake.queued || processIdentityLiveness(state.input_wake.writer) !== 'gone'))
31
+ return state;
32
+ elected = true;
33
+ return { ...state, input_wake: { incarnation, token, queued: false, writer } };
34
+ });
35
+ if (!elected) {
36
+ log?.debug('delivery.handoff', { route: 'input-wake', stage: 'coalesced', session: sessionId });
37
+ return;
38
+ }
39
+ let sent = false;
40
+ try {
41
+ sent = await send(sessionInputWake());
42
+ log?.info('delivery.handoff', { route: 'input-wake', stage: sent ? 'queued' : 'deferred', session: sessionId });
43
+ if (sent)
44
+ updateSessionState(sessionId, env, (state) => state.input_wake?.token === token
45
+ ? { ...state, input_wake: { ...state.input_wake, queued: true } } : state);
46
+ }
47
+ finally {
48
+ if (!sent)
49
+ updateSessionState(sessionId, env, (state) => {
50
+ if (state.input_wake?.token !== token)
51
+ return state;
52
+ const next = { ...state };
53
+ delete next.input_wake;
54
+ return next;
55
+ });
56
+ }
57
+ }
58
+ export function observeSessionInputWake(sessionId, env, prompt) {
59
+ if (prompt !== sessionInputWake())
60
+ return;
61
+ updateSessionState(sessionId, env, (state) => {
62
+ const next = { ...state };
63
+ delete next.input_wake;
64
+ return next;
65
+ });
66
+ }
67
+ export function stageSessionAnswers(sessionId, env, accepted) {
68
+ updateSessionState(sessionId, env, (state) => {
69
+ if (state.accepted?.recorded_at !== accepted.recorded_at)
70
+ return state;
71
+ const waiting = [...(state.waiting_answers ?? [])];
72
+ for (const answer of accepted.answers) {
73
+ if (!waiting.some((entry) => entry.pending.request_id === answer.pending.request_id))
74
+ waiting.push(answer);
75
+ }
76
+ const next = { ...state, waiting_answers: waiting };
77
+ delete next.accepted;
78
+ return next;
79
+ });
80
+ // A reply proves submission even when its HTTP receipt was lost. Wake a
81
+ // dormant resident writer without depending on that missing receipt.
82
+ recordSessionNotified(sessionId, env, accepted.recorded_at);
83
+ }
84
+ /** The existing route wakes the exact owner, but no longer owns answer text. */
85
+ export function sessionInputRoute(sessionId, env, route, log) {
86
+ return { ...route, defer: async (accepted) => {
87
+ stageSessionAnswers(sessionId, env, accepted);
88
+ await wakeSessionInputs(sessionId, env, async (text) => {
89
+ const result = await route.deliver({
90
+ context: text, answers: 0, remaining: 0, request_ids: [], journal_recorded_at: accepted.recorded_at,
91
+ commitDelivery: () => !sessionHasEnded(sessionId, env),
92
+ });
93
+ return result.acknowledgement === 'delivered';
94
+ }, log);
95
+ } };
96
+ }
97
+ function messagesPath(sessionId, env) {
98
+ return path.join(stateDir(env), 'sessions', `${sanitizeSessionId(sessionId)}.inputs.json`);
99
+ }
100
+ /** Cache only: the service remains authoritative and claims fence stale copies. */
101
+ export function stageSessionMessages(sessionId, env, lease, messages) {
102
+ atomicWriteFileSync(messagesPath(sessionId, env), JSON.stringify({ session_id: sessionId, ...lease, messages }));
103
+ }
104
+ export function readSessionMessages(sessionId, env, lease) {
105
+ try {
106
+ const data = JSON.parse(readFileSync(messagesPath(sessionId, env), 'utf8'));
107
+ if (data.session_id !== sessionId || data.incarnation !== lease.incarnation || data.generation !== lease.generation || !Array.isArray(data.messages))
108
+ return [];
109
+ if (!data.messages.every((m) => typeof m.message_id === 'string' && /^sm_[A-Za-z0-9_-]+$/.test(m.message_id) &&
110
+ typeof m.created_at === 'string' && typeof m.agent_acknowledgement_text_required === 'boolean' &&
111
+ (m.kind === 'note' ? typeof m.body === 'string' : m.kind === 'answer_edit' && typeof m.request_id === 'string' && typeof m.text === 'string' && Array.isArray(m.answers))))
112
+ return [];
113
+ return data.messages;
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ }
119
+ function pendingSessionInputs(sessionId, env, lease) {
120
+ const state = readSessionState(sessionId, env);
121
+ const written = new Set(readDeliveryJournal(sessionId, env)
122
+ .filter((entry) => ['writing', 'written', 'failed'].includes(entry.stage))
123
+ .map((entry) => entry.subject.type === 'answer' ? entry.subject.request_id : entry.subject.message_id));
124
+ const owed = new Set(state.acknowledgement_due?.map((entry) => entry.request_id));
125
+ const answers = (state.waiting_answers ?? []).filter((answer) => answer.pending.request_id !== undefined && !written.has(answer.pending.request_id) &&
126
+ owed.has(answer.pending.request_id)).slice(0, 20);
127
+ // Answers precede their edits; notes retain the service's immutable order.
128
+ const messages = (lease === null ? [] : readSessionMessages(sessionId, env, lease))
129
+ .filter((message) => !written.has(message.message_id)).slice(0, 20 - answers.length);
130
+ return { answers, messages };
131
+ }
132
+ export function hasSessionInputs(sessionId, env, lease) {
133
+ const { answers, messages } = pendingSessionInputs(sessionId, env, lease);
134
+ return answers.length + messages.length > 0;
135
+ }
136
+ /** One stdout document, at most 20 inputs, with ownership checked at the byte. */
137
+ export async function drainSessionInputs(input) {
138
+ const { sequencer: deps, lease } = input;
139
+ const { answers, messages } = pendingSessionInputs(deps.sessionId, deps.env, lease);
140
+ if (answers.length + messages.length === 0 || !input.mayWrite())
141
+ return false;
142
+ // An unfenced answer has no server claim to reject a stale local copy.
143
+ // Reconcile it before presentation; inability to check must defer it.
144
+ for (const answer of answers.filter((entry) => entry.delivery_claim !== true)) {
145
+ try {
146
+ const result = await deps.client.agentAcknowledgement(answer.pending.request_id, { waitSeconds: 0 });
147
+ if (result.agent_acknowledgement !== null)
148
+ clearAcknowledgementObligation(deps.sessionId, deps.env, answer.pending.request_id);
149
+ }
150
+ catch {
151
+ return false;
152
+ }
153
+ }
154
+ const claimUntil = deps.monotonic() + 750;
155
+ const handOff = await beginHandOff(deps, {
156
+ lease, lockWaitMs: 0, stopAtRefusal: true, mayWrite: input.mayWrite,
157
+ mayClaim: () => deps.monotonic() < claimUntil,
158
+ subjects: [
159
+ ...answers.filter((answer) => answer.delivery_claim === true).map((answer) => ({ type: 'answer', request_id: answer.pending.request_id })),
160
+ ...messages.map((message) => ({ type: 'session_message', message_id: message.message_id })),
161
+ ],
162
+ earlierAnswerWriterGone: (subject) => {
163
+ const message = subject.type === 'session_message' ? messages.find((entry) => entry.message_id === subject.message_id) : undefined;
164
+ return message?.kind === 'answer_edit' && answerWriterGone(deps.sessionId, deps.env, message.request_id);
165
+ },
166
+ });
167
+ if (handOff === null)
168
+ return false;
169
+ const terminal = new Set(handOff.refused.filter((entry) => entry.reason === 'not_claimable' || entry.reason === 'not_found')
170
+ .flatMap((entry) => entry.subject.type === 'answer' ? [entry.subject.request_id] : []));
171
+ if (terminal.size > 0)
172
+ updateSessionState(deps.sessionId, deps.env, (latest) => ({
173
+ ...latest, waiting_answers: (latest.waiting_answers ?? []).filter((answer) => !terminal.has(answer.pending.request_id)),
174
+ }));
175
+ const ids = new Set(handOff.claimed.map((claim) => claim.subject.type === 'answer' ? claim.subject.request_id : claim.subject.message_id));
176
+ // A concurrent consumer may have drained an unclaimed answer while this
177
+ // reader waited for the delivery lock. Re-read while holding that lock.
178
+ const current = readSessionState(deps.sessionId, deps.env);
179
+ const readyAnswers = answers.filter((answer) => current.waiting_answers?.some((entry) => entry.pending.request_id === answer.pending.request_id) &&
180
+ current.acknowledgement_due?.some((entry) => entry.request_id === answer.pending.request_id) &&
181
+ (answer.delivery_claim !== true || ids.has(answer.pending.request_id)));
182
+ const readyMessages = messages.filter((message) => ids.has(message.message_id));
183
+ if (readyAnswers.length + readyMessages.length === 0 || !input.mayWrite() || !handOff.writable()) {
184
+ await handOff.finish('not-written');
185
+ return false;
186
+ }
187
+ const text = [
188
+ ...(readyAnswers.length === 0 ? [] : [answersContext(readyAnswers, current.pending?.length ?? 0)]),
189
+ ...readyMessages.map(sessionMessageContext),
190
+ ].join('\n\n');
191
+ let began = false;
192
+ let outputAttempted = false;
193
+ const restoreUnwritten = () => {
194
+ updateSessionState(deps.sessionId, deps.env, (latest) => ({
195
+ ...latest, waiting_answers: [
196
+ ...readyAnswers.filter((answer) => latest.acknowledgement_due?.some((owed) => owed.request_id === answer.pending.request_id) &&
197
+ !latest.waiting_answers?.some((entry) => entry.pending.request_id === answer.pending.request_id)),
198
+ ...(latest.waiting_answers ?? []),
199
+ ],
200
+ }));
201
+ for (const message of readyMessages) {
202
+ if (!current.message_acknowledgement_due?.some((entry) => entry.message_id === message.message_id)) {
203
+ clearAcknowledgementObligation(deps.sessionId, deps.env, message.message_id);
204
+ }
205
+ }
206
+ };
207
+ try {
208
+ if (!handOff.begin(() => !sessionHasEnded(deps.sessionId, deps.env))) {
209
+ await handOff.finish('not-written');
210
+ return false;
211
+ }
212
+ began = true;
213
+ // Persist consumption before stdout; an ambiguous output is never replayed.
214
+ const consumed = new Set(readyAnswers.map((answer) => answer.pending.request_id));
215
+ updateSessionState(deps.sessionId, deps.env, (latest) => {
216
+ const retiring = [...(latest.retiring ?? [])];
217
+ for (const answer of readyAnswers) {
218
+ const entry = retiringQuestion(answer.pending, 'answered');
219
+ if (entry !== null && !retiring.some((item) => item.request_id === entry.request_id))
220
+ retiring.push(entry);
221
+ }
222
+ return { ...latest, waiting_answers: (latest.waiting_answers ?? []).filter((answer) => !consumed.has(answer.pending.request_id)), retiring };
223
+ });
224
+ for (const message of readyMessages)
225
+ recordMessageAcknowledgementDue(deps.sessionId, deps.env, {
226
+ message_id: message.message_id, recorded_at: deps.wall(), text_required: message.agent_acknowledgement_text_required,
227
+ });
228
+ if (!input.mayWrite() || !handOff.writable()) {
229
+ restoreUnwritten();
230
+ await handOff.finish('aborted');
231
+ return false;
232
+ }
233
+ outputAttempted = true;
234
+ input.write(text);
235
+ if (readyAnswers.length > 0)
236
+ updateSessionState(deps.sessionId, deps.env, (latest) => ({
237
+ ...latest, continuation: { answered_at: deps.wall(), count: (latest.continuation?.count ?? 0) + 1 },
238
+ }));
239
+ await handOff.finish('written');
240
+ deps.log?.info('delivery.handoff', {
241
+ route: 'input-drain', stage: 'presented', answers: readyAnswers.length, messages: readyMessages.length,
242
+ request_ids: readyAnswers.map((answer) => answer.pending.request_id), message_ids: readyMessages.map((message) => message.message_id),
243
+ oldest_message_age_ms: Math.max(0, ...readyMessages.map((message) => deps.wall() - Date.parse(message.created_at))),
244
+ });
245
+ return true;
246
+ }
247
+ catch (error) {
248
+ if (began && !outputAttempted)
249
+ restoreUnwritten();
250
+ await handOff.finish(outputAttempted ? 'failed' : began ? 'aborted' : 'not-written');
251
+ throw error;
252
+ }
253
+ }
254
+ //# sourceMappingURL=session-inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-inputs.js","sourceRoot":"","sources":["../src/session-inputs.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { answerWriterGone, beginHandOff } from './session-delivery.js';
4
4
  export async function handOffSessionMessages(messages, attendant, deps) {
5
5
  const { sequencer } = deps;
6
6
  const log = sequencer.log;
7
- // The service lists messages in acceptance (revision) order, which is the
7
+ // The service lists messages in immutable acceptance order, which is the
8
8
  // User's order. Timestamps can tie and identifiers are random, so neither
9
9
  // may reorder them: a later edit must never land before an earlier one.
10
10
  for (const message of messages) {
@@ -26,6 +26,7 @@ export async function handOffSessionMessages(messages, attendant, deps) {
26
26
  await handOff.finish('not-written');
27
27
  switch (refusal.reason) {
28
28
  case 'awaiting_earlier_answer':
29
+ case 'awaiting_earlier_message':
29
30
  case 'attempt_pending':
30
31
  case 'unavailable':
31
32
  // Later messages keep their order behind this one.
@@ -36,6 +37,10 @@ export async function handOffSessionMessages(messages, attendant, deps) {
36
37
  case 'not_claimable':
37
38
  case 'not_found':
38
39
  continue;
40
+ default: {
41
+ const unsupported = refusal.reason;
42
+ throw new Error(`Unsupported claim refusal: ${unsupported}`);
43
+ }
39
44
  }
40
45
  }
41
46
  let owed = false;
@@ -1 +1 @@
1
- {"version":3,"file":"session-message-handoff.js","sourceRoot":"","sources":["../src/session-message-handoff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-message-handoff.js","sourceRoot":"","sources":["../src/session-message-handoff.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "schema_version": 1,
3
- "package_version": "11.6.0",
3
+ "package_version": "11.6.1-beta.3",
4
4
  "skill": "notifai",
5
- "digest": "sha256:0511417b155da2a4a49d9651f86ac2776ffa2728068d59cfb3932a4f6fbadcee",
5
+ "digest": "sha256:906a99db20da2ee59d8f742a939348a8ea1034bc64a9e37099583751a0bc8141",
6
6
  "files": [
7
7
  {
8
8
  "path": "SKILL.md",
9
- "sha256": "f3c6cdb16d2cfbac365e0837598be88115c10618c1e2a858da3acc84bbafb484"
9
+ "sha256": "2eb952db3a6042050efd46c7b8e5cf92f655aed0ed5e0d8b31840af580839e79"
10
10
  },
11
11
  {
12
12
  "path": "references/diagnostics.md",
13
- "sha256": "d68d55833d3a3a6f88b1a178560d28584bfd1bea926c43e251149c3b28a0ffad"
13
+ "sha256": "b58e15432b52e68fb9b1325255ca19a77a438dd31f130707366818959f82351c"
14
14
  },
15
15
  {
16
16
  "path": "references/harness-setup.md",
17
- "sha256": "0dbbd305db20c6342fc2df0d165d3f9ab122f451fbca7e5529fd6aa109629fd4"
17
+ "sha256": "ff8a3219e92da67f0985de1ac992c73f18180b6d3694cc2b87e082dba4c5e8f8"
18
18
  },
19
19
  {
20
20
  "path": "references/notes-and-edits.md",
21
- "sha256": "f420e4a18dc7e95d66d0e4d46e595d64eb802e065592d71e4a2e572c328956a5"
21
+ "sha256": "54b47b432f86e42ddc0ffee7822ed9f3ecdfc4d97e6318aa36ad90ccf1fd6738"
22
22
  },
23
23
  {
24
24
  "path": "references/send-details.md",
@@ -92,16 +92,13 @@ without an exact Agent Session is a usage error. With an exact identifier:
92
92
  notifai send --kind done \
93
93
  --session-label "Account creation" \
94
94
  --title "Users can now create accounts" \
95
- --summary "Sign-up, verification, and login now work on staging." \
96
- --body "Sign-up, email verification, and login work end to end on staging. Next: password reset, unless you want something else first."
95
+ --summary "Sign-up, verification, and login now work on staging."
97
96
  ```
98
97
 
99
- Without that identifier, omit `--session-label` and carry only Project context.
100
-
101
98
  Outside a Project, or on a Projectless request, pass `--projectless`; it stops
102
99
  cwd or config from inventing a Project.
103
100
 
104
- `--kind` is required, and it is the most consequential word you choose:
101
+ `--kind` is required and controls insistence:
105
102
 
106
103
  | kind | what it means | how it arrives |
107
104
  | --- | --- | --- |
@@ -111,7 +108,7 @@ cwd or config from inventing a Project.
111
108
  | `blocked` | no User reply would resume the work | attention tone |
112
109
  | `question` | set for you by `--reply` and by `ask` — never pass it | attention tone |
113
110
 
114
- **Declare the kind that is true**: it sets the notification's insistence.
111
+ **Declare the kind that is true.**
115
112
 
116
113
  Work needs a User response? [Ask an answerable question](#ask-a-question).
117
114
  Use one-way blocked only when no User reply would resume the work.
@@ -132,14 +129,13 @@ Images (`--image`, referenced in Body as `media:1`), grouping, replacement,
132
129
  and the User-owned `--sound`, `--level`, and `--device`:
133
130
  [Sending details](references/send-details.md).
134
131
 
132
+ Without that identifier, omit `--session-label`.
135
133
  Project and Agent Session are inferred; never pass `--session-id`.
136
134
  `--session-label` is 2-6 words about the Agent Session, never the Project, branch,
137
135
  status, result, identifier, hash, or filesystem path.
138
136
  The initial name comes from the environment when available, then your label,
139
137
  then a generated fallback. Repeat the same `--session-label` on sends and asks;
140
- changing that flag does not rename an existing semantic name. A later semantic
141
- name can replace a generated fallback. Companion Apps show the Account's current
142
- label, including a User rename.
138
+ changing that flag does not rename an existing semantic name. A semantic name can replace a generated fallback; Companion Apps show the current Account label.
143
139
 
144
140
  ### Keep the Agent Session name current
145
141
 
@@ -147,12 +143,10 @@ At each change of job, check whether the current name still describes the work.
147
143
  If the job changed completely enough that the old name would mislead the User,
148
144
  run `notifai session rename "New job"` when starting the new job, without
149
145
  waiting for a notification or User reminder. Keep the name for milestones,
150
- ordinary progress, and same-job refinements. Account creation to search
151
- indexing merits a rename; testing account creation does not.
146
+ ordinary progress, and same-job refinements. Rename for a new job, never its testing milestone.
152
147
 
153
- The command updates the Account, then the local name; use the new name in later
154
- sends and asks. It accepts no Agent Session id and needs the active harness to
155
- prove the exact current Agent Session. A harness title change alone does not
148
+ The command updates the Account and local name; use it in later sends and asks.
149
+ It takes no Agent Session id: the active harness must prove the exact session. A harness title change alone does not
156
150
  rename an existing Notifai semantic label.
157
151
 
158
152
  ## Ask a question
@@ -183,8 +177,8 @@ notifai ask "Which environment should I roll out to?" \
183
177
 
184
178
  `--json` returns choice ids and `question_id`.
185
179
 
186
- `registered: true` is local only. It has not yet been submitted as a
187
- Notification Request and has no Provider Acceptance. Never call a question sent
180
+ `registered: true` confirms local registration only, not submission or
181
+ Provider Acceptance. Background submission starts immediately. Never call a question sent
188
182
  or delivered from registration alone. Settlement adds `request_id`, keeping
189
183
  `question_id`. Inspect:
190
184
 
@@ -195,9 +189,9 @@ notifai status <question_id> --json
195
189
  States: `local`, `frozen`, `live`, `answered`, `withdrawn`, `retired`.
196
190
 
197
191
  **Registering is not the end of the turn.** Ask in plain conversational text,
198
- say what each answer will make you do, then end the turn to start submission.
199
- A harness form can remain pending after a reply. Follow higher-priority rules;
200
- neither path retires the other.
192
+ say what each answer will make you do, and continue independent work.
193
+ Submission does not wait for turn end; answer-dependent work waits for the reply.
194
+ A harness form can remain pending after a reply; neither path retires the other.
201
195
 
202
196
  **Never say where the answer must arrive** ("tell me here"). The harness owns routing.
203
197
 
@@ -247,6 +241,11 @@ resume later. Never create a duplicate. On exit 0, act on the answer.
247
241
 
248
242
  ## When the answer arrives
249
243
 
244
+ When a wake-up names `notifai receive`, run that exact command
245
+ to read pending notes and answers together. An empty result means continue.
246
+ The wake-up contains no answer and needs no acknowledgement; never recover an
247
+ old answer from it. Hooks may have delivered the input already.
248
+
250
249
  The latest reply is the user's current word: later choices correct earlier
251
250
  ones; typed parts are read together in order. A relayed answer uses the chosen
252
251
  label; `notifai replies <request_id> --json` has stable choice ids.
@@ -270,8 +269,8 @@ notifai acknowledge <request_id> --text "Rolling out to staging now; I'll report
270
269
  Keep it under 200 characters and name only the concrete work their reply
271
270
  causes: it is a receipt, not a report.
272
271
 
273
- If the written reply is off, Notifai prints the command without `--text`; run
274
- exactly that. The acknowledgement is never optional.
272
+ If written replies are off, run the printed command without `--text`.
273
+ Acknowledgement is required.
275
274
 
276
275
  Then resume the committed work without asking them to confirm again; it is
277
276
  work you are resuming, not approval you received.
@@ -22,7 +22,7 @@ hook never ran.
22
22
  `hook.gate` records carry a fixed `reason` — `notifications-off`,
23
23
  `claimed-elsewhere`, `no-question`, `no-session`, `answered`,
24
24
  `acknowledgement-required`, `acknowledgement-abandoned`, `harness-cannot-continue`,
25
- `continuation-repeat`, `continuation-limit`, `delivery-limit`, `proceeding` —
25
+ `continuation-limit`, `delivery-limit`, `proceeding` —
26
26
  so filter on that, never on the wording of a message. `notifications-off` is
27
27
  the one the user deliberately never sees, which is why it is worth ruling out
28
28
  before concluding anything is broken.
@@ -127,12 +127,17 @@ shell. Do not strip markers or borrow another Agent Session's identity to make
127
127
  skill and guidance as the new Notification Request owner.
128
128
  - **Codex:** run `notifai hooks install --harness codex`. If `hooks-trust`
129
129
  fails, open `/hooks` in Codex and approve or enable the Notifai handlers.
130
- The synchronous `PostToolUse` handler delivers Session Notes and Answer Edits
130
+ The synchronous `PostToolUse` handler delivers pending answers, Session Notes and Answer Edits
131
131
  after tools during an active turn. Install and approve that handler, then
132
132
  start a fresh Agent Session to use the new attendant and hook definitions.
133
133
  Busy delivery starts after that exact session first runs the trusted hook;
134
- until then, and while idle, Notes use the native queue. A running tool must
134
+ until then, and while idle, the native queue carries a wake-up to read current
135
+ pending input. It never carries note or answer text. A running tool must
135
136
  return before its hook runs.
137
+ Automatic goal continuations are observed at their first trusted tool
138
+ callback even when the harness emits no prompt hook. Notes still need an
139
+ available callback; a long tool or uninterrupted reasoning cannot be cut
140
+ short by this route.
136
141
  Then start one fresh Agent Session, send one prompt, and run `notifai doctor`. If
137
142
  SessionStart is absent, reinstall the current hooks and start a fresh Agent Session;
138
143
  UserPromptSubmit does not activate it. Codex SubagentStart uses the same
@@ -185,7 +190,7 @@ shell. Do not strip markers or borrow another Agent Session's identity to make
185
190
  On macOS, the loaded Gateway service can route an asynchronous `notifai ask` answer
186
191
  into the same Agent Session after the asking turn ends. It queues a pointer
187
192
  through OpenClaw's followup route; run `notifai replies <id>` from that
188
- session to read the answer and `notifai acknowledge <id>` after acting on it.
193
+ session to read the answer and `notifai acknowledge <id>` before acting on it.
189
194
  Question Routing requires the current generation marker, an enabled Project,
190
195
  and a local Gateway whose CLI version and process identity match the plugin.
191
196
  If this Project is disabled, run `notifai project enable` before `notifai ask`.
@@ -216,7 +221,8 @@ shell. Do not strip markers or borrow another Agent Session's identity to make
216
221
  a Note may interrupt a working turn. The plugin checks the current session
217
222
  before each write, and the agent must acknowledge the message. An attended
218
223
  classic CLI session can route an `ask` answer into that same live session;
219
- end the asking turn and leave Hermes running for the answer window. If the
224
+ keep Hermes running for the answer window. Submission starts immediately;
225
+ the plugin owns answer delivery. If the
220
226
  process exits first, it does not cold-resume and the answer is not delivered.
221
227
  TUI, gateway, API, ACP, remote terminal backends, and Windows remain outside
222
228
  this proven cell.
@@ -240,28 +246,30 @@ reports each harness's supported route separately.
240
246
  The session that registered a question owns the answer's return. The last
241
247
  meter differs per harness:
242
248
 
243
- - **Claude Code on POSIX:** the Stop hook is asynchronous. It returns at once,
244
- so the turn is never held and the terminal stays the user's, and the same
245
- process keeps waiting out of band for the complete answer window. When the
246
- answer arrives it is posted to that Agent Session's own inbox socket: an idle
247
- Agent Session starts a new turn with it, and a busy one receives it when its
248
- current turn ends. An Agent Session that is provably gone is cold-resumed
249
+ - **Claude Code on POSIX:** a detached observer starts after submission and
250
+ waits out of band for the complete answer window. The resident Session
251
+ Attendant sends wakes with Claude's required child-process ancestry. Stop
252
+ can recover answer ownership without holding the turn. When the
253
+ answer arrives it is stored with the session's pending inputs. Its own inbox
254
+ socket receives a wake-up: an idle Agent Session starts a new turn, and a busy
255
+ one receives it when its current turn ends. The prompt hook or the named
256
+ `notifai receive` command drains the current notes and answers together.
257
+ An Agent Session that is provably gone is cold-resumed with the wake-up
249
258
  instead — never one whose liveness probe cannot rule it out.
250
259
  - **Claude Code on Windows:** the Stop hook stays held through the complete
251
260
  answer window. When the answer arrives it returns `decision: block`, starting
252
261
  the successor turn in the same Agent Session without another User prompt.
253
262
  Direct inbox wake is unavailable, but it is not needed while this exact Stop
254
263
  continuation owns the answer.
255
- - **Codex:** the asynchronous Stop hook releases the turn and waits in the
256
- background for the complete answer window. When an answer arrives, Notifai
264
+ - **Codex:** a detached observer starts after submission and waits in the
265
+ background for the complete answer window; Stop provides recovery. When an answer arrives, Notifai
257
266
  invokes `codex queue` for the exact Agent Session in the same Codex home.
258
- A live idle session starts a turn, a busy one consumes the answer after its
259
- current turn, and a closed one keeps the queued answer until it is reopened.
260
- Queue success proves storage, not consumption; UserPromptSubmit observes
261
- consumption. Keep the original question and request identities if the route
262
- fails so Notifai's journal can recover the answer. Never queue and resume the
263
- same answer separately: a resume can consume the queue and the repeated
264
- prompt, producing two copies.
267
+ Only a wake-up is queued. Pending notes and answers remain in Notifai until
268
+ a trusted tool hook, prompt hook, or `notifai receive` drains a bounded batch.
269
+ A late wake-up cannot repeat an acknowledged answer: it contains no answer
270
+ text. Queue success proves wake storage, not input presentation. Inputs are
271
+ claimed immediately before presentation; uncertain writes are never replayed.
272
+ Keep the original question and request identities when investigating a delay.
265
273
  - **Grok:** the Stop hook stays held through the complete answer window and
266
274
  returns the answer as a decision block to the same Agent Session. Its native
267
275
  `stopHookActive` flag on the successor Stop confirms consumption. There is no
@@ -270,25 +278,22 @@ meter differs per harness:
270
278
  owner process or its route fails. It is not the normal last meter for an
271
279
  unexpired question.
272
280
 
273
- Registration alone starts no waiter. Normally the asking turn's Stop starts
274
- submission; if a new User prompt overtakes it, UserPromptSubmit launches a
275
- detached settlement owner for unmatched registrations. That recovery can
276
- submit and queue a Codex answer while the new turn is active. It does not make
277
- `ask` an immediate-send command or remove the installed Stop requirement.
281
+ `ask` durably registers the question and immediately launches submission. It
282
+ does not wait for Stop or hold the command for the answer window. Stop and
283
+ UserPromptSubmit recover outstanding work; they are not required to begin
284
+ normal submission. Registration is not evidence of Provider Acceptance.
278
285
 
279
- Keep supervision obligations when a question blocks only part of the work.
280
- If the coordinator must remain active, use the skill's foreground `send --reply`
281
- flow only when its managed command can stay alive for the complete answer
282
- window while the coordinator supervises, then consume and acknowledge its
283
- result. Otherwise settle or explicitly transfer supervision before an `ask`
284
- handoff. Ending a turn neither completes delegated work nor transfers ownership.
286
+ Continue independent work and supervision while the question is outstanding.
287
+ Only answer-dependent work waits. Delivery into the agent still follows the
288
+ harness boundaries above; immediate submission does not make every harness
289
+ able to inject an answer during a running turn.
285
290
 
286
291
  Keep the original identity when an answer has not arrived. Queue acceptance
287
292
  does not prove consumption, and expiry, retirement, or recovery failure can
288
293
  prevent resumption. Inspect `status` and `replies` instead of re-asking.
289
294
 
290
295
  At the `ask_grace_seconds` default of `0`, the question reaches devices as soon
291
- as the asking turn ends. A positive value keeps it in the terminal for that
296
+ as registration starts background submission. A positive value keeps it in the terminal for that
292
297
  long first, so an answer typed there wins without a notification ever leaving.
293
298
  `reply_window_seconds` then controls how long the answer is accepted and how
294
299
  long Question Routing keeps an exact return path to this Agent Session. The
@@ -352,8 +357,9 @@ Those are three different controls and only the last one decides whether an
352
357
  answer is still wanted. Question Routing owns that complete window. Claude Code
353
358
  waits out of band and wakes the Agent Session on POSIX; on Windows its Stop
354
359
  stays held and returns the answer as the same Agent Session's continuation,
355
- while Codex queues the answer into its Agent Session's durable inbox. The
356
- journal is crash recovery, not the ordinary delivery path.
360
+ while Codex queues a wake-up into its Agent Session's durable inbox. Codex and
361
+ POSIX Claude keep pending input locally until a foreground drain; the native
362
+ wake never stores a second copy of the User's answer.
357
363
 
358
364
  `NOTIFAI_NO_INPUT=1` guarantees no command will ever prompt, which is what you
359
365
  want in CI or any shell with nobody at it. `NOTIFAI_CREDENTIALS=file` stores the