thinkpool-pair 0.7.349 → 0.7.351
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/code-event-contract.mjs +5 -4
- package/lane-lifecycle.mjs +9 -7
- package/package.json +1 -1
- package/terminal-name.mjs +11 -5
package/code-event-contract.mjs
CHANGED
|
@@ -16,8 +16,8 @@ const E = EVENT_CLASS.DURABLE_DELIVERY_EVIDENCE
|
|
|
16
16
|
|
|
17
17
|
// Exhaustive over every kind currently emitted into a Code room, its retained log,
|
|
18
18
|
// or the durable __agent notification stream. `answer`/`control`/etc. are commands
|
|
19
|
-
// replayed by the transcript; they are not durable decision records.
|
|
20
|
-
//
|
|
19
|
+
// replayed by the transcript; they are not durable decision records. Pair control
|
|
20
|
+
// supplies actor-bound decision records and authoritative verification receipts.
|
|
21
21
|
// Adding a producer without adding its kind here is a test/dev error and a
|
|
22
22
|
// fail-closed production value.
|
|
23
23
|
export const CODE_EVENT_REGISTRY = Object.freeze({
|
|
@@ -82,9 +82,10 @@ export function classifyCodeEvent (eventOrKind, { strict = strictByDefault() } =
|
|
|
82
82
|
// Only delivery evidence currently has the archive-level durability contract.
|
|
83
83
|
durable: eventClass === E,
|
|
84
84
|
replayable: eventClass !== V,
|
|
85
|
-
//
|
|
85
|
+
// Pair control supplies actor-bound authorization. Classification alone never does.
|
|
86
86
|
authorizes: false,
|
|
87
|
-
//
|
|
87
|
+
// `completes` means an authority-verified outcome, not a runtime turn boundary.
|
|
88
|
+
// A successful result can settle execution while remaining unverified.
|
|
88
89
|
completes: false,
|
|
89
90
|
})
|
|
90
91
|
}
|
package/lane-lifecycle.mjs
CHANGED
|
@@ -107,10 +107,12 @@ export function projectLaneLifecycle ({
|
|
|
107
107
|
} else if (event.kind === 'result') {
|
|
108
108
|
if (RESULT_CANCELED.has(event.subtype)) out = base(LIFECYCLE_STATE.CANCELED, null, { rawStatus })
|
|
109
109
|
else if (event.subtype && event.subtype !== 'success') out = base(LIFECYCLE_STATE.FAILED, null, { rawStatus })
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
110
|
+
// A successful result is authoritative for the execution boundary: the
|
|
111
|
+
// runtime turn finished and the lane is idle. It is not proof that the
|
|
112
|
+
// worker's findings or changed product behavior were independently
|
|
113
|
+
// verified. Keep that evidence dimension in `verified`; pair-control
|
|
114
|
+
// receipts, not transcript claims, are the only authority for upgrading it.
|
|
115
|
+
else out = base(LIFECYCLE_STATE.DONE, null, { rawStatus })
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -137,9 +139,9 @@ export function projectFlowLifecycle (rawStatus) {
|
|
|
137
139
|
return base(LIFECYCLE_STATE.BLOCKED, BLOCKED_REASON.DEPENDENCY, { rawStatus })
|
|
138
140
|
case 'failed': return base(LIFECYCLE_STATE.FAILED, null, { rawStatus })
|
|
139
141
|
case 'cancelled': case 'canceled': return base(LIFECYCLE_STATE.CANCELED, null, { rawStatus })
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
case 'done': return base(LIFECYCLE_STATE.
|
|
142
|
+
// `done` is the Flow execution boundary. Commits and artifacts remain
|
|
143
|
+
// unverified evidence until an authority-bound receipt observes them.
|
|
144
|
+
case 'done': return base(LIFECYCLE_STATE.DONE, null, { rawStatus })
|
|
143
145
|
default: return base(LIFECYCLE_STATE.BLOCKED, BLOCKED_REASON.NEEDS_INPUT, { rawStatus })
|
|
144
146
|
}
|
|
145
147
|
}
|
package/package.json
CHANGED
package/terminal-name.mjs
CHANGED
|
@@ -221,6 +221,10 @@ export function cleanTerminalName(value) {
|
|
|
221
221
|
if (!name || GENERIC.test(name) || nativeClaudeProviderAccessFailed(name)) return null
|
|
222
222
|
if (/^(?:error|failed|sorry|unable|i (?:cannot|can't)|rate limit|request failed)\b/i.test(name)) return null
|
|
223
223
|
if (name.length > 48) name = name.slice(0, 48).replace(/\s+\S*$/, '').trim()
|
|
224
|
+
const words = name.split(/\s+/).filter(Boolean)
|
|
225
|
+
const compactCjk = words.length === 1
|
|
226
|
+
&& /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u.test(name)
|
|
227
|
+
if ((words.length < 2 && !compactCjk) || words.length > 4) return null
|
|
224
228
|
return name || null
|
|
225
229
|
}
|
|
226
230
|
|
|
@@ -264,7 +268,7 @@ const taskTitle = (value) => {
|
|
|
264
268
|
if (!body) return null
|
|
265
269
|
const grammar = analyzeGrammar(body)
|
|
266
270
|
if (grammar.negativePreference) {
|
|
267
|
-
const subject = contentWords(negativePreferenceSubject(grammar)).slice(0,
|
|
271
|
+
const subject = contentWords(negativePreferenceSubject(grammar)).slice(0, 3)
|
|
268
272
|
return subject.length ? cleanTerminalName(['Avoid', ...subject.map(titleWord)].join(' ')) : null
|
|
269
273
|
}
|
|
270
274
|
const informationRequest = grammar.informationRequest
|
|
@@ -282,11 +286,11 @@ const taskTitle = (value) => {
|
|
|
282
286
|
if (!verb && /\bopen(?:s|ed|ing)?\b/i.test(body)) verb = 'Open'
|
|
283
287
|
|
|
284
288
|
if (/\bautomatic(?:ally)?\b[\s\S]{0,24}\bnam(?:e|ing)\b/i.test(signalText) && /\bterminals?\b/i.test(signalText)) {
|
|
285
|
-
if (/\bcontext\b[\s\S]{0,24}\broom\b|\broom\b[\s\S]{0,24}\bcontext\b/i.test(signalText)) return 'Auto-Name Terminals From
|
|
289
|
+
if (/\bcontext\b[\s\S]{0,24}\broom\b|\broom\b[\s\S]{0,24}\bcontext\b/i.test(signalText)) return 'Auto-Name Terminals From Context'
|
|
286
290
|
verb = 'Auto-Name'
|
|
287
291
|
}
|
|
288
|
-
if (verb === 'Snap' && /\bterminal row\b/i.test(signalText) && /\bview\b/i.test(signalText)) return 'Snap Terminal Row
|
|
289
|
-
if (verb === 'Snap' && /\bclicked terminal\b/i.test(signalText) && /\bview\b/i.test(signalText)) return 'Snap Clicked Terminal
|
|
292
|
+
if (verb === 'Snap' && /\bterminal row\b/i.test(signalText) && /\bview\b/i.test(signalText)) return 'Snap Terminal Row View'
|
|
293
|
+
if (verb === 'Snap' && /\bclicked terminal\b/i.test(signalText) && /\bview\b/i.test(signalText)) return 'Snap Clicked Terminal View'
|
|
290
294
|
|
|
291
295
|
let domain = []
|
|
292
296
|
let objectText = body
|
|
@@ -305,7 +309,9 @@ const taskTitle = (value) => {
|
|
|
305
309
|
const available = object.findIndex((word) => /^available$/i.test(word))
|
|
306
310
|
if (available > 0) object = [object[available], ...object.slice(0, available), ...object.slice(available + 1)]
|
|
307
311
|
}
|
|
308
|
-
const picked = [...domain, ...object]
|
|
312
|
+
const picked = [...domain, ...object]
|
|
313
|
+
.filter((word, index, all) => all.findIndex((other) => other.toLowerCase() === word.toLowerCase()) === index)
|
|
314
|
+
.slice(0, verb ? 3 : 4)
|
|
309
315
|
if (!picked.length) return null
|
|
310
316
|
return cleanTerminalName([verb, ...picked.map(titleWord)].filter(Boolean).join(' '))
|
|
311
317
|
}
|