@@ -12,16 +12,14 @@ import hooksManifest from './hooks/hooks.json'
1212 * call sites — a hand-maintained trigger table in the tool layer. That table is
1313 * gone: the mint decision now lives at the adapter port, where reaching for a
1414 * bound credential (`boundHttp`) IS the declaration that an identity is needed.
15- * So the derivation is traced from there instead, which is also what
16- * `comms-tww6` specifies:
15+ * So the derivation is traced from there instead:
1716 *
1817 * A TOOL WHOSE ADAPTER PATH REACHES `boundHttp` MUST RECEIVE `session_id`
1918 * AND BE IN THE `hooks.json` MATCHER.
2019 *
2120 * That is a stronger rule than the old one. The old test could only catch a
2221 * tool that called the wrapper and was missing from the matcher; it could not
23- * see a tool that reached `boundHttp` while appearing in neither set — which is
24- * exactly the live P1 that `comms-tww6` is open about.
22+ * see a tool that reached `boundHttp` while appearing in neither set.
2523 *
2624 * RECEIVES, NOT DECLARES (comms-tg70). The rule used to say DECLARE, and traced
2725 * a `session_id` property on the tool's advertised `inputSchema`. No tool
@@ -37,24 +35,25 @@ import hooksManifest from './hooks/hooks.json'
3735 * satisfies all of them by looking at nothing. Pinning the receiving set makes
3836 * the scan itself the thing under test: rename the marker and the pin fails
3937 * loudly instead of the suite passing quietly.
40- *
41- * KNOWN VIOLATIONS ARE NAMED, NOT PAPERED OVER. Three tools violate the rule at
42- * HEAD (see `TWW6_EXCEPTIONS`). Fixing them means giving them the host-supplied
43- * `session_id`, which is out of scope here. Encoding the real rule with a
44- * visible exception list beats asserting a weaker rule that passes: the day
45- * `comms-tww6` lands, its author deletes entries from that list and this test
46- * proves the fix.
4738 */
4839
4940/**
5041 * Publisher verbs whose adapter implementation reaches `boundHttp`. Pinned
51- * rather than parsed: two of them reach it through shared helpers
42+ * rather than parsed: three of them reach it through shared helpers
5243 * (`setThreadResolved`, `setChannelDescription`), which no line-wise scan
5344 * resolves honestly. `adapterVerbsReachingBoundHttp` below guards the pin, so a
5445 * verb that joins or leaves the seam fails this suite rather than silently
5546 * widening the set a tool has to be stamped for.
5647 */
57- const BOUND_VERBS = [ 'post' , 'edit' , 'react' , 'unreact' ] as const
48+ const BOUND_VERBS = [
49+ 'post' ,
50+ 'edit' ,
51+ 'react' ,
52+ 'unreact' ,
53+ 'resolveThread' ,
54+ 'unresolveThread' ,
55+ 'setChannelDescription' ,
56+ ] as const
5857
5958/**
6059 * Declarations in `packages/zulip/adapter.ts` that call `boundHttp()`. The two
@@ -131,10 +130,9 @@ const ATTACHMENT_DEP_ADAPTER_MEMBER: Readonly<Record<string, string>> = {
131130 * Tools that reach `boundHttp` through an inbox verb while sitting outside the
132131 * matcher, so the hook never stamps them and the bind seam sees no session id.
133132 *
134- * EMPTY, and it has to stay that way. An unstamped inbox verb is not a
135- * `comms-tww6`-style attribution accident — it cannot inherit an earlier
136- * call's seat, because `boundHttp` consults the binder on every call and
137- * refuses outright when the context carries no session id. It simply FAILS.
133+ * EMPTY, and it has to stay that way. An unstamped inbox verb cannot inherit an
134+ * earlier call's seat, because `boundHttp` consults the binder on every call
135+ * and refuses outright when the context carries no session id. It simply FAILS.
138136 *
139137 * The matcher was widened to the seven tools that declare `session_id`, which
140138 * REVERSES commit `0f0e755` (PR #126) — that commit chose id-blind subscribe
@@ -147,18 +145,7 @@ const ATTACHMENT_DEP_ADAPTER_MEMBER: Readonly<Record<string, string>> = {
147145const G5ZH3_MATCHER_PENDING = [ ] as const
148146
149147/**
150- * Tools that reach `boundHttp` while receiving no `session_id` and sitting
151- * outside the matcher — the open P1 `comms-tww6`. They run under whatever seat
152- * an EARLIER call happened to bind, so their attribution is inherited by
153- * accident of ordering rather than established by the call itself.
154- *
155- * Delete an entry here when that tool gains `session_id`; the assertion below
156- * then holds it to the rule.
157- */
158- const TWW6_EXCEPTIONS = [ 'resolve_thread' , 'set_channel_description' , 'unresolve_thread' ] as const
159-
160- /**
161- * Every tool that accepts a host-supplied `session_id`. EIGHT, the same eight
148+ * Every tool that accepts a host-supplied `session_id`. ELEVEN, the same eleven
162149 * the PreToolUse matcher stamps today — but the two sets answer different
163150 * questions and are allowed to diverge again: `subscribe` and `unsubscribe`
164151 * are here for a non-CC ephemeral host that supplies the UUID itself, and a
@@ -173,8 +160,11 @@ const SESSION_ID_RECEIVING_TOOLS = [
173160 'edit_message' ,
174161 'post' ,
175162 'react' ,
163+ 'resolve_thread' ,
164+ 'set_channel_description' ,
176165 'subscribe' ,
177166 'unreact' ,
167+ 'unresolve_thread' ,
178168 'unsubscribe' ,
179169 'upload_file' ,
180170] as const
@@ -340,7 +330,7 @@ test('the set of adapter declarations reaching boundHttp is the pinned one', asy
340330// them reads "no tool violates this", which a scan that matches nothing
341331// satisfies trivially — so assert first that the scan finds the set it is
342332// supposed to find.
343- test ( 'the tools accepting a host-supplied session_id are exactly the pinned eight ' , async ( ) => {
333+ test ( 'the tools accepting a host-supplied session_id are exactly the pinned eleven ' , async ( ) => {
344334 const facts = toolFactsFromToolsSource ( await toolsSource ( ) )
345335 const receiving = [ ...facts ]
346336 . filter ( ( [ , f ] ) => f . receivesSessionId )
@@ -454,18 +444,6 @@ test('the tools that bind via an inbox verb but are unstamped are exactly the re
454444 expect ( unstamped ) . toEqual ( [ ...G5ZH3_MATCHER_PENDING ] )
455445} )
456446
457- // The rule stated over ALL bound verbs, including the two helper-backed ones
458- // the tool layer never stamps. This is the assertion `comms-tww6` closes.
459- test ( 'comms-tww6: the known unstamped bound-path tools are exactly the recorded exceptions' , async ( ) => {
460- const facts = toolFactsFromToolsSource ( await toolsSource ( ) )
461- const boundHttpVerbs = new Set ( [ 'resolveThread' , 'unresolveThread' , 'setChannelDescription' ] )
462- const unstamped = [ ...facts ]
463- . filter ( ( [ , f ] ) => [ ...f . verbs ] . some ( ( v ) => boundHttpVerbs . has ( v ) ) && ! f . receivesSessionId )
464- . map ( ( [ name ] ) => name )
465- . sort ( )
466- expect ( unstamped ) . toEqual ( [ ...TWW6_EXCEPTIONS ] )
467- } )
468-
469447test ( 'the matcher carries no tool that never reaches boundHttp and never binds' , async ( ) => {
470448 const facts = toolFactsFromToolsSource ( await toolsSource ( ) )
471449 const matched = alternationToolsFromMatcher ( injectSessionIdMatcher ( hooksManifest ) )
0 commit comments