@theronap/cortex-mcp 0.9.78 → 0.9.80
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/lib/server.mjs +44 -2
- package/lib/timeline_claim_receipt.mjs +25 -0
- package/package.json +1 -1
package/lib/server.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import { runSendImessage } from './imessage_send.mjs'
|
|
|
11
11
|
import { formatGrepHits } from './grep_cli.mjs'
|
|
12
12
|
import { renderTriage } from './red_link_triage.mjs'
|
|
13
13
|
import { runCodeGraphQuery } from './code_graph_cli.mjs'
|
|
14
|
+
import { renderTimelineClaimReceipt } from './timeline_claim_receipt.mjs'
|
|
14
15
|
|
|
15
16
|
// Reactive red-link triage (Mechanism 2). On a read_page miss, ask the server whether the name is a
|
|
16
17
|
// tracked wanted page, whether a bare node exists for it, and whether it's a deliberately demoted page,
|
|
@@ -299,8 +300,12 @@ export async function runServer(version) {
|
|
|
299
300
|
const body = await res.text()
|
|
300
301
|
throw new Error(classify(res.status, res.headers.get('content-type'), body, res.headers.get('x-vercel-id')).message)
|
|
301
302
|
}
|
|
302
|
-
const { threads, records } = await res.json()
|
|
303
|
-
|
|
303
|
+
const { threads, records, claim } = await res.json()
|
|
304
|
+
const receipt = renderTimelineClaimReceipt(claim)
|
|
305
|
+
if (!threads?.length && !records?.length) {
|
|
306
|
+
const empty = 'Nothing in the backlog — everything captured so far has been claimed.'
|
|
307
|
+
return { content: [{ type: 'text', text: receipt ? `${empty}\n\n${receipt}` : empty }] }
|
|
308
|
+
}
|
|
304
309
|
|
|
305
310
|
const sections = []
|
|
306
311
|
|
|
@@ -329,10 +334,47 @@ export async function runServer(version) {
|
|
|
329
334
|
sections.push(`Unclaimed records (${records.length}) from other sources — newest first:\n${lines.join('\n')}`)
|
|
330
335
|
}
|
|
331
336
|
|
|
337
|
+
if (receipt) sections.push(receipt)
|
|
332
338
|
return { content: [{ type: 'text', text: sections.join('\n\n') }] }
|
|
333
339
|
},
|
|
334
340
|
)
|
|
335
341
|
|
|
342
|
+
// Read-only evidence status for the Gate 4 live trial. This MUST remain an aggregate query: a
|
|
343
|
+
// monitor needs to know whether enough sessions have exercised the loop, not who they were or what
|
|
344
|
+
// work they handled. In particular, it must never call timeline_pull as a shortcut, since that would
|
|
345
|
+
// manufacture the evidence it claims to observe.
|
|
346
|
+
server.registerTool(
|
|
347
|
+
'gate4_status',
|
|
348
|
+
{
|
|
349
|
+
title: 'Gate 4 live-evidence status',
|
|
350
|
+
description: 'Read the aggregate, rolling-window status of the Gate 4 trial. This does not claim, attribute, resolve, or expose captured work. It reports machine-observable session, attribution, and recovery counts; a human still confirms that the qualifying sessions were normal work.',
|
|
351
|
+
inputSchema: {
|
|
352
|
+
days: z.number().optional().describe('rolling observation window in days (default 14; capped at 30)'),
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
async ({ days }) => {
|
|
356
|
+
const qs = typeof days === 'number' ? `?days=${encodeURIComponent(String(days))}` : ''
|
|
357
|
+
const res = await fetchCortex(`${BASE}/api/timeline/observation${qs}`, { headers: { Authorization: `Bearer ${TOKEN}` } })
|
|
358
|
+
if (!res.ok) {
|
|
359
|
+
const body = await res.text()
|
|
360
|
+
throw new Error(classify(res.status, res.headers.get('content-type'), body, res.headers.get('x-vercel-id')).message)
|
|
361
|
+
}
|
|
362
|
+
const s = await res.json()
|
|
363
|
+
const machine = s.machineEvidencePassed ? 'MET' : 'NOT YET MET'
|
|
364
|
+
return {
|
|
365
|
+
content: [{ type: 'text', text:
|
|
366
|
+
`Gate 4 evidence, last ${s.window?.days ?? 14} days\n` +
|
|
367
|
+
`- session claims: ${s.sessionCount ?? 0}/3\n` +
|
|
368
|
+
`- session-attributed completions: ${s.attributedDone ?? 0} (need 1+)\n` +
|
|
369
|
+
`- expiry recoveries: ${s.recoveredClaims ?? 0} (need 1+)\n` +
|
|
370
|
+
`- anonymous session claims: ${s.anonymousSessionClaims ?? 0} (need 0)\n` +
|
|
371
|
+
`- non-session rows in window (reported, excluded): ${s.nonSessionClaims ?? 0}\n\n` +
|
|
372
|
+
`Machine evidence: ${machine}. Human attestation remains required: qualifying sessions must be normal work, not a staged demo.`,
|
|
373
|
+
}],
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
)
|
|
377
|
+
|
|
336
378
|
server.registerTool(
|
|
337
379
|
'search_org',
|
|
338
380
|
{
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Render the route's claim envelope rather than inferring success from the rows it returned. A pull
|
|
2
|
+
// without this receipt is the exact failure mode Gate 4 is trying to rule out: work can be leased (or
|
|
3
|
+
// not leased) invisibly, and a reader has no way to distinguish the two.
|
|
4
|
+
export function renderTimelineClaimReceipt(claim) {
|
|
5
|
+
if (!claim || typeof claim !== 'object' || Array.isArray(claim)) return ''
|
|
6
|
+
|
|
7
|
+
if (claim.active !== true) {
|
|
8
|
+
if (claim.reason === 'session_key_required') {
|
|
9
|
+
return 'Viewing only — no session key was supplied, so no work was leased or attributed.'
|
|
10
|
+
}
|
|
11
|
+
if (claim.reason === 'disabled') return 'Viewing only — claiming was disabled, so no work was leased or attributed.'
|
|
12
|
+
return ''
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const leased = Number(claim.leased)
|
|
16
|
+
const count = Number.isFinite(leased) && leased >= 0 ? Math.trunc(leased) : null
|
|
17
|
+
const expiry = typeof claim.leasedUntil === 'string' && claim.leasedUntil ? claim.leasedUntil : null
|
|
18
|
+
|
|
19
|
+
if (count === null) return 'Claim receipt: this session requested work; the server did not return a valid lease count.'
|
|
20
|
+
if (count === 0) return 'Claim receipt: no work was leased to this session.'
|
|
21
|
+
|
|
22
|
+
const noun = count === 1 ? 'record' : 'records'
|
|
23
|
+
return `Claim receipt: ${count} ${noun} leased to this session${expiry ? ` until ${expiry}` : ''}. ` +
|
|
24
|
+
'Attribute only email threads you genuinely recognize; leave unknown work unjudged.'
|
|
25
|
+
}
|