@adhdev/mesh-shared 1.0.60-rc.40 → 1.0.60-rc.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +21 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -5
- package/dist/index.mjs.map +1 -1
- package/dist/turn-evidence.d.ts +9 -2
- package/dist/types.d.ts +11 -0
- package/package.json +1 -1
- package/src/turn-evidence.ts +14 -1
- package/src/types.ts +8 -0
- package/src/worker-protocol.ts +24 -2
package/dist/turn-evidence.d.ts
CHANGED
|
@@ -87,7 +87,7 @@ export type NoProgressObservedStatus = SessionStatus | 'unknown';
|
|
|
87
87
|
* Reasons a turn hold exists. Holds are attempt-scoped only (C2: delivery-side
|
|
88
88
|
* waits are consumer deferral on the `turn.deliver` cursor, not hold rows).
|
|
89
89
|
*/
|
|
90
|
-
export declare const HOLD_REASONS: readonly ["await_delivery", "await_consume", "await_turn", "liveness", "hard_ceiling", "live_pending", "transcript_quiet", "weak_candidate", "suspension_before_consumed"];
|
|
90
|
+
export declare const HOLD_REASONS: readonly ["await_delivery", "await_consume", "await_turn", "liveness", "hard_ceiling", "live_pending", "transcript_quiet", "weak_candidate", "suspension_before_consumed", "await_report"];
|
|
91
91
|
export type HoldReason = typeof HOLD_REASONS[number];
|
|
92
92
|
export declare const TURN_OUTCOMES: readonly ["completed", "failed", "cancelled"];
|
|
93
93
|
export type TurnOutcome = typeof TURN_OUTCOMES[number];
|
|
@@ -207,6 +207,13 @@ export type TurnEvidenceBody = {
|
|
|
207
207
|
releasedByHardCap?: boolean;
|
|
208
208
|
nativeOutcome?: NativeTurnOutcome;
|
|
209
209
|
live?: LiveTurnPending;
|
|
210
|
+
/**
|
|
211
|
+
* Stamped (true only) by the WORKER's daemon when the session holds a live
|
|
212
|
+
* worker-MCP session bind, i.e. the worker can call report_completion. The
|
|
213
|
+
* owner then treats a genuine end as a report-awaiting candidate (R9r), not
|
|
214
|
+
* a commit. Absent = no reporting surface = today's genuine-end commit.
|
|
215
|
+
*/
|
|
216
|
+
reportExpected?: boolean;
|
|
210
217
|
} | {
|
|
211
218
|
kind: 'transcript_final';
|
|
212
219
|
selfAttributing: boolean;
|
|
@@ -327,7 +334,7 @@ export declare const isEvidenceSourceId: (value: unknown) => value is "fsm_edge"
|
|
|
327
334
|
export declare const isTurnEvidenceKind: (value: unknown) => value is "no_progress" | "delivered" | "liveness" | "turn_end" | "transcript_final" | "session_error" | "dispatch_failed" | "dispatch_accepted" | "delivery_refused" | "duplicate_dispatch_refusal" | "session_rebound" | "turn_started" | "suspension" | "suspension_resolved" | "transcript_activity" | "process_exit" | "worker_report" | "worker_progress" | "git_side_effect" | "cancel" | "operator_status" | "coordinator_ack" | "hold_expired";
|
|
328
335
|
export declare const isTurnReason: (value: unknown) => value is "intentional_cleanup" | "operator_cancel" | "task_removed" | "mission_abandoned" | "superseded" | "operator_update" | "refine_terminal" | "validation_terminal" | "hard_ceiling" | "turn_end" | "weak_end_confirmed" | "transcript_final" | "worker_reported" | "finalization_timeout_no_response" | "session_error" | "provider_auth_failed" | "provider_billing_failed" | "reclaim_budget_exhausted" | "hollow_max_retries" | "migration_orphan" | "dispatch_refused_session_exited" | "dispatch_refused_no_target" | "dispatch_refused_unsupported_input" | "dispatch_failed" | "session_exit" | "session_exit_before_turn" | "session_dead" | "hollow_completion" | "assigned_stranded_dispatch_unconfirmed" | "delivered_not_consumed_redrive" | "delivered_no_turn_deadline";
|
|
329
336
|
export declare const isNotifyKind: (value: unknown) => value is "stopped" | "failed" | "no_progress" | "completed" | "cancelled" | "approval" | "choice" | "approval_resolved" | "candidate" | "progress" | "late_completion" | "mesh_event";
|
|
330
|
-
export declare const isHoldReason: (value: unknown) => value is "await_delivery" | "await_consume" | "await_turn" | "liveness" | "hard_ceiling" | "live_pending" | "transcript_quiet" | "weak_candidate" | "suspension_before_consumed";
|
|
337
|
+
export declare const isHoldReason: (value: unknown) => value is "await_delivery" | "await_consume" | "await_turn" | "liveness" | "hard_ceiling" | "live_pending" | "transcript_quiet" | "weak_candidate" | "suspension_before_consumed" | "await_report";
|
|
331
338
|
export declare const isTurnOutcome: (value: unknown) => value is "failed" | "completed" | "cancelled";
|
|
332
339
|
export declare const isCommitStrength: (value: unknown) => value is "operator" | "genuine" | "weak" | "tool_report";
|
|
333
340
|
export declare function isEvidenceIdentifier(value: unknown): value is string;
|
package/dist/types.d.ts
CHANGED
|
@@ -136,4 +136,15 @@ export interface RepoMeshSessionStatus {
|
|
|
136
136
|
startedAt?: string | null;
|
|
137
137
|
lastActivityAt?: string | null;
|
|
138
138
|
isCached?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Worker MCP delivery outcome for this session's launch (present only for a
|
|
141
|
+
* mesh-delegated launch). `reason` is a short enum code, never free text —
|
|
142
|
+
* see `WORKER_MCP_DELIVERY_REASONS` (daemon-core's `mesh/worker-mcp-isolation.ts`,
|
|
143
|
+
* the source of the vocabulary this field's values are drawn from; not
|
|
144
|
+
* re-exported here so mesh-shared stays a dependency-free leaf).
|
|
145
|
+
*/
|
|
146
|
+
workerMcp?: {
|
|
147
|
+
delivered: boolean;
|
|
148
|
+
reason?: string;
|
|
149
|
+
};
|
|
139
150
|
}
|
package/package.json
CHANGED
package/src/turn-evidence.ts
CHANGED
|
@@ -122,6 +122,11 @@ export type NoProgressObservedStatus = SessionStatus | 'unknown'
|
|
|
122
122
|
export const HOLD_REASONS = [
|
|
123
123
|
'await_delivery', 'await_consume', 'await_turn', 'liveness', 'hard_ceiling',
|
|
124
124
|
'live_pending', 'transcript_quiet', 'weak_candidate', 'suspension_before_consumed',
|
|
125
|
+
// A genuine FSM end of a mesh turn whose worker holds a live worker-MCP bind:
|
|
126
|
+
// the structured report is the primary evidence (design §F2), so the idle edge
|
|
127
|
+
// only opens this hold (R9r) — a report commits (R17), a new busy edge cancels
|
|
128
|
+
// it as a false idle (R12r), expiry commits weak (R13r).
|
|
129
|
+
'await_report',
|
|
125
130
|
] as const
|
|
126
131
|
export type HoldReason = typeof HOLD_REASONS[number]
|
|
127
132
|
|
|
@@ -211,7 +216,14 @@ export type TurnEvidenceBody =
|
|
|
211
216
|
| { kind: 'suspension'; modal: SuspensionModal; modalKey?: string }
|
|
212
217
|
| { kind: 'suspension_resolved'; resolution: SuspensionResolution; via: SuspensionResolutionVia }
|
|
213
218
|
| { kind: 'turn_end'; strength: TurnEndStrength; afterFinalizationTimeout?: boolean; hollow?: boolean; summary?: SummaryRef
|
|
214
|
-
blockReason?: TurnEndBlockReason; releasedByHardCap?: boolean; nativeOutcome?: NativeTurnOutcome; live?: LiveTurnPending
|
|
219
|
+
blockReason?: TurnEndBlockReason; releasedByHardCap?: boolean; nativeOutcome?: NativeTurnOutcome; live?: LiveTurnPending
|
|
220
|
+
/**
|
|
221
|
+
* Stamped (true only) by the WORKER's daemon when the session holds a live
|
|
222
|
+
* worker-MCP session bind, i.e. the worker can call report_completion. The
|
|
223
|
+
* owner then treats a genuine end as a report-awaiting candidate (R9r), not
|
|
224
|
+
* a commit. Absent = no reporting surface = today's genuine-end commit.
|
|
225
|
+
*/
|
|
226
|
+
reportExpected?: boolean }
|
|
215
227
|
| { kind: 'transcript_final'; selfAttributing: boolean; nativeRead: boolean; nativeMarker?: NativeTurnMarkerRef
|
|
216
228
|
live: LiveTurnPending; summary?: SummaryRef; messageAt?: number }
|
|
217
229
|
| { kind: 'transcript_activity'; newestActivityAt: number }
|
|
@@ -296,6 +308,7 @@ export const TURN_EVIDENCE_FIELD_SPECS: TurnEvidenceFieldSpecs = {
|
|
|
296
308
|
strength: en(TURN_END_STRENGTHS), afterFinalizationTimeout: boolOpt, hollow: boolOpt,
|
|
297
309
|
summary: { t: 'summary_ref', optional: true }, blockReason: enOpt(TURN_END_BLOCK_REASONS),
|
|
298
310
|
releasedByHardCap: boolOpt, nativeOutcome: enOpt(NATIVE_TURN_OUTCOMES), live: { t: 'live', optional: true },
|
|
311
|
+
reportExpected: boolOpt,
|
|
299
312
|
},
|
|
300
313
|
transcript_final: {
|
|
301
314
|
selfAttributing: bool, nativeRead: bool, nativeMarker: { t: 'native_marker', optional: true },
|
package/src/types.ts
CHANGED
|
@@ -153,4 +153,12 @@ export interface RepoMeshSessionStatus {
|
|
|
153
153
|
startedAt?: string | null
|
|
154
154
|
lastActivityAt?: string | null
|
|
155
155
|
isCached?: boolean
|
|
156
|
+
/**
|
|
157
|
+
* Worker MCP delivery outcome for this session's launch (present only for a
|
|
158
|
+
* mesh-delegated launch). `reason` is a short enum code, never free text —
|
|
159
|
+
* see `WORKER_MCP_DELIVERY_REASONS` (daemon-core's `mesh/worker-mcp-isolation.ts`,
|
|
160
|
+
* the source of the vocabulary this field's values are drawn from; not
|
|
161
|
+
* re-exported here so mesh-shared stays a dependency-free leaf).
|
|
162
|
+
*/
|
|
163
|
+
workerMcp?: { delivered: boolean; reason?: string }
|
|
156
164
|
}
|
package/src/worker-protocol.ts
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
import { renderMissionBriefBlock, type MissionBrief } from './mission-brief'
|
|
34
|
+
import { isMeshTaskDifficulty } from './brain-routing'
|
|
34
35
|
|
|
35
36
|
export const WORKER_TOOLS = [
|
|
36
37
|
'report_completion',
|
|
@@ -78,7 +79,23 @@ export function renderWorkerProtocolFooter(input: WorkerProtocolFooterInput = {}
|
|
|
78
79
|
const scope: string[] = []
|
|
79
80
|
if (input.taskId) scope.push(`task ${input.taskId}`)
|
|
80
81
|
if (input.taskMode) scope.push(`mode ${input.taskMode}`)
|
|
81
|
-
|
|
82
|
+
// MCP-usage-audit item 2: validate against the canonical difficulty set
|
|
83
|
+
// (this package's own brain-routing vocabulary — never duplicated here)
|
|
84
|
+
// rather than rendering an internal caller's typo or stale value verbatim.
|
|
85
|
+
// The MCP tool-schema enum already blocks a bad value AT THE TOOLS; this
|
|
86
|
+
// covers internal callers that can still construct a task with one.
|
|
87
|
+
if (input.difficulty) {
|
|
88
|
+
if (isMeshTaskDifficulty(input.difficulty)) {
|
|
89
|
+
scope.push(`difficulty ${input.difficulty}`)
|
|
90
|
+
} else {
|
|
91
|
+
// eslint-disable-next-line no-console -- mesh-shared is a dependency-free
|
|
92
|
+
// leaf with no logger abstraction; this is the one place that matters.
|
|
93
|
+
console.warn(
|
|
94
|
+
`[worker-protocol] task ${input.taskId ?? '(unknown)'}: dropping invalid difficulty '${input.difficulty}' `
|
|
95
|
+
+ `from the worker footer (expected one of easy, medium, difficult, freeform)`,
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
82
99
|
if (input.readonly) scope.push('read-only')
|
|
83
100
|
if (scope.length) lines.push(`You are a delegated worker (${scope.join(', ')}).`)
|
|
84
101
|
else lines.push('You are a delegated worker.')
|
|
@@ -89,10 +106,15 @@ export function renderWorkerProtocolFooter(input: WorkerProtocolFooterInput = {}
|
|
|
89
106
|
'For work that runs longer than a few minutes, call `progress_update` at natural checkpoints so the '
|
|
90
107
|
+ 'coordinator can see you are alive without polling.',
|
|
91
108
|
'`peer_context_pull` shows what sibling tasks in this mission have reported; `git_status` / `git_diff` / '
|
|
92
|
-
+ '`git_log` inspect your own workspace
|
|
109
|
+
+ '`git_log` inspect your own workspace — all three REQUIRE the absolute path to it as `workspace`.',
|
|
93
110
|
'You have no coordinator tools (no `mesh_*`) by design: do not enqueue, dispatch, or restart anything. '
|
|
94
111
|
+ 'If you need a decision from the coordinator, finish with `report_completion` and outcome `blocked`, '
|
|
95
112
|
+ 'listing what you need in `blockers`.',
|
|
113
|
+
'On a code-changing task, `report_completion` with outcome `completed` requires `touched_files` — send '
|
|
114
|
+
+ '`[]` if you changed nothing, omitting the field is what gets refused. `blocked`/`failed` never need it, '
|
|
115
|
+
+ 'and a read-only task should omit it or send `[]`.',
|
|
116
|
+
'If `report_completion` is refused, the response carries `validationErrors` (or a `hint`) naming exactly '
|
|
117
|
+
+ 'what to fix — correct that field and call it again; a refusal records nothing.',
|
|
96
118
|
)
|
|
97
119
|
if (input.enclosedHandoffNotes && input.enclosedHandoffNotes > 0) {
|
|
98
120
|
lines.push(
|