Kevin Crutt commited on
Commit
b872afa
·
1 Parent(s): 491a8b9

liris: add triad host router gulp pipeline

Browse files
docs/LIRIS-TRIAD-HOST-ROUTER-GULP-PIPELINE-2026-06-14.hbp ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ TRIADROUTCANONHDR|doc=LIRIS-TRIAD-HOST-ROUTER-GULP-PIPELINE-2026-06-14|date=2026-06-14|owner=liris|scope=8-byte-host-router-rule-of-three-gulp-gc-cube-feedback|tag=DESCRIPTOR-ONLY|json=0
2
+ TRIADROUTCANONHOST|host_handle_bytes=8|meaning=local-host-process-or-portal-descriptor|not_meaning=message-size-or-free-provider-compute|node_per_agent=0|process_launch=0|json=0
3
+ TRIADROUTCANONROUTERS|surfaces=opencode+openai+codex+gemini+claude+anthropic+big-pickle+registered-cli|rule=registered-descriptor-before-use;provider-terms-and-auth-apply;billing-bypass-0|remote_call=0|json=0
4
+ TRIADROUTCANONTHREE|roles=real-agent+self-reflect-agent+fabric-reflect-agent|supervisor=sees-all-three|nesting=allowed-as-descriptor-recursion-only-until-emitter-cosign|json=0
5
+ TRIADROUTCANONGC|gulp_messages=2000|super_gulp_messages=50000|after_processing=1|message_body_retention=0|summary_hash_retention=1|json=0
6
+ TRIADROUTCANONCUBE|watchers=gnn+reverse-sieve-gnn+omnishannon+white-room|output=cube-catalog-feedback|self_improvement=bounded-by-tests-sidecars-cosign|json=0
7
+ TRIADROUTCANONTOOL|tool=tools/behcs/triad-host-router-gulp-pipeline.mjs|test=tests/triad-host-router-gulp-pipeline.unit.test.mjs|catalog=tools/behcs/fabric-agent-preload-catalog.mjs|json=0
8
+ TRIADROUTCANONFTR|status=SEALED-HOST-ROUTER-GULP-PIPELINE|next=use-before-scaling-router-agent-claims|json=0
docs/LIRIS-TRIAD-HOST-ROUTER-GULP-PIPELINE-2026-06-14.hbp.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 9F2E3343A22E869B604A83691E92FAB036A8D07FC3BFF5E4B55A552F517F7374 LIRIS-TRIAD-HOST-ROUTER-GULP-PIPELINE-2026-06-14.hbp
tests/fabric-agent-preload-catalog.unit.test.mjs CHANGED
@@ -31,6 +31,7 @@ test('preload catalog includes the laws, tools, roles, and cadence agents need',
31
  assert.ok(TOOLS.some((t) => t.id === 'tool-skill-registry-matrix' && t.gate.includes('live-tool-execution-0')));
32
  assert.ok(TOOLS.some((t) => t.id === 'program-cube-ingestion-map' && t.gate.includes('blind_mutation-0')));
33
  assert.ok(TOOLS.some((t) => t.id === 'agent-cost-layer-boundary' && t.gate.includes('free_compute_claim-0')));
 
34
  assert.ok(ROLES.some((r) => r.id === 'flywheel' && r.must_do.includes('compare-to-acer-local-truth')));
35
  assert.ok(WORKFLOW.join('-').includes('memory-index-plan'));
36
  assert.equal(toolById('token-cube-catalog-binder').gate, 'mint-write-live-DEFER_TO_OPERATOR');
 
31
  assert.ok(TOOLS.some((t) => t.id === 'tool-skill-registry-matrix' && t.gate.includes('live-tool-execution-0')));
32
  assert.ok(TOOLS.some((t) => t.id === 'program-cube-ingestion-map' && t.gate.includes('blind_mutation-0')));
33
  assert.ok(TOOLS.some((t) => t.id === 'agent-cost-layer-boundary' && t.gate.includes('free_compute_claim-0')));
34
+ assert.ok(TOOLS.some((t) => t.id === 'triad-host-router-gulp-pipeline' && t.gate.includes('provider_bypass-0')));
35
  assert.ok(ROLES.some((r) => r.id === 'flywheel' && r.must_do.includes('compare-to-acer-local-truth')));
36
  assert.ok(WORKFLOW.join('-').includes('memory-index-plan'));
37
  assert.equal(toolById('token-cube-catalog-binder').gate, 'mint-write-live-DEFER_TO_OPERATOR');
tests/fabric-agent-preload-catalog.unit.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- B7A3C228CA853E528E617EB02910AF243A49116A1A8FDF90D2420269ECFB84B0 fabric-agent-preload-catalog.unit.test.mjs
 
1
+ FB438698865603D1DFA7ADF8230C2B9E98662A4B924854C04880FE88673D968A fabric-agent-preload-catalog.unit.test.mjs
tests/supervisor-collision-router.system.test.mjs CHANGED
@@ -91,6 +91,7 @@ const sealedFiles = [
91
  'docs/LIRIS-SELFHEAL-200STEP-INTEGRATION-2026-06-13.hbp',
92
  'docs/LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14.hbp',
93
  'docs/LIRIS-AGENT-COST-LAYER-BOUNDARY-2026-06-14.hbp',
 
94
  'docs/ACER-SLICE-ENGINE-LIVE-CRANK-RECEIPT-2026-06-13.hbp',
95
  'docs/LIRIS-ROUTE-HEALTH-BASELINE-2026-06-13.hbp',
96
  'docs/ACER-ROUTE-HEALTH-CROSS-VANTAGE-2026-06-13.hbp',
@@ -233,6 +234,7 @@ const sealedFiles = [
233
  'tools/behcs/tool-skill-registry-matrix.mjs',
234
  'tools/behcs/program-cube-ingestion-map.mjs',
235
  'tools/behcs/agent-cost-layer-boundary.mjs',
 
236
  'tools/behcs/logical-extreme-stress.mjs',
237
  'tools/behcs/logical-stress-cube-feed.mjs',
238
  'tools/behcs/brown-hilbert-expansion-stress.mjs',
@@ -269,6 +271,7 @@ const sealedFiles = [
269
  'tests/tool-skill-registry-matrix.unit.test.mjs',
270
  'tests/program-cube-ingestion-map.unit.test.mjs',
271
  'tests/agent-cost-layer-boundary.unit.test.mjs',
 
272
  'tests/logical-extreme-stress.unit.test.mjs',
273
  'tests/logical-stress-cube-feed.unit.test.mjs',
274
  'tests/brown-hilbert-expansion-stress.unit.test.mjs',
 
91
  'docs/LIRIS-SELFHEAL-200STEP-INTEGRATION-2026-06-13.hbp',
92
  'docs/LIRIS-PROGRAM-CUBE-INGESTION-MAP-2026-06-14.hbp',
93
  'docs/LIRIS-AGENT-COST-LAYER-BOUNDARY-2026-06-14.hbp',
94
+ 'docs/LIRIS-TRIAD-HOST-ROUTER-GULP-PIPELINE-2026-06-14.hbp',
95
  'docs/ACER-SLICE-ENGINE-LIVE-CRANK-RECEIPT-2026-06-13.hbp',
96
  'docs/LIRIS-ROUTE-HEALTH-BASELINE-2026-06-13.hbp',
97
  'docs/ACER-ROUTE-HEALTH-CROSS-VANTAGE-2026-06-13.hbp',
 
234
  'tools/behcs/tool-skill-registry-matrix.mjs',
235
  'tools/behcs/program-cube-ingestion-map.mjs',
236
  'tools/behcs/agent-cost-layer-boundary.mjs',
237
+ 'tools/behcs/triad-host-router-gulp-pipeline.mjs',
238
  'tools/behcs/logical-extreme-stress.mjs',
239
  'tools/behcs/logical-stress-cube-feed.mjs',
240
  'tools/behcs/brown-hilbert-expansion-stress.mjs',
 
271
  'tests/tool-skill-registry-matrix.unit.test.mjs',
272
  'tests/program-cube-ingestion-map.unit.test.mjs',
273
  'tests/agent-cost-layer-boundary.unit.test.mjs',
274
+ 'tests/triad-host-router-gulp-pipeline.unit.test.mjs',
275
  'tests/logical-extreme-stress.unit.test.mjs',
276
  'tests/logical-stress-cube-feed.unit.test.mjs',
277
  'tests/brown-hilbert-expansion-stress.unit.test.mjs',
tests/supervisor-collision-router.system.test.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 8EA12D638DDCA38A99DD49D5B905D0122FABF543AF234351A761AFA972BFD752 supervisor-collision-router.system.test.mjs
 
1
+ 66B2C303BA2A59E603FA6C3CAE56F9FCE48D3F4E3D659554A9C980959739AE70 supervisor-collision-router.system.test.mjs
tests/triad-host-router-gulp-pipeline.unit.test.mjs ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import assert from 'node:assert/strict';
2
+ import { readFileSync } from 'node:fs';
3
+ import test from 'node:test';
4
+
5
+ import {
6
+ FEEDBACK_STAGES, GULP_MESSAGES, HOST_HANDLE_BYTES, ROUTER_SURFACES, SUPER_GULP_MESSAGES,
7
+ TRIAD_ROLES, buildPipeline, emitRows, normalizeRouter, selfTest, triadForMessage,
8
+ } from '../tools/behcs/triad-host-router-gulp-pipeline.mjs';
9
+
10
+ test('triad host-router pipeline self-test passes', () => {
11
+ assert.equal(selfTest().ok, true);
12
+ });
13
+
14
+ test('host process doctrine is encoded as an 8-byte descriptor, not a node process per agent', () => {
15
+ const built = buildPipeline();
16
+ assert.equal(HOST_HANDLE_BYTES, 8);
17
+ assert.equal(built.summary.no_node_per_agent, true);
18
+ assert.equal(built.summary.live_ready, false);
19
+ assert.ok(built.routers.every((r) => r.host_handle_bytes === 8 && r.node_per_agent === 0));
20
+ });
21
+
22
+ test('rule of three produces real, self-reflect, and fabric-reflect handles for the supervisor', () => {
23
+ const triad = triadForMessage({ message_id: 'operator-message-1' });
24
+ assert.deepEqual(TRIAD_ROLES.map((r) => r.id), ['real-agent', 'self-reflect-agent', 'fabric-reflect-agent']);
25
+ assert.equal(triad.length, 3);
26
+ assert.equal(new Set(triad.map((r) => r.handle8)).size, 3);
27
+ assert.ok(triad.every((r) => r.process_launch === 0 && r.remote_call === 0));
28
+ });
29
+
30
+ test('gulp and super-gulp GC sizes are fixed and watcher stages are present', () => {
31
+ assert.equal(GULP_MESSAGES, 2000);
32
+ assert.equal(SUPER_GULP_MESSAGES, 50000);
33
+ assert.ok(FEEDBACK_STAGES.includes('message-gulp-gc'));
34
+ assert.ok(FEEDBACK_STAGES.includes('reverse-sieve-gnn-proposal'));
35
+ assert.ok(FEEDBACK_STAGES.includes('omnishannon-novelty'));
36
+ assert.ok(FEEDBACK_STAGES.includes('white-room-review'));
37
+ assert.ok(FEEDBACK_STAGES.includes('cube-catalog-feedback'));
38
+ });
39
+
40
+ test('provider and CLI routers are descriptors with authorization gates', () => {
41
+ const built = buildPipeline();
42
+ assert.ok(built.routers.some((r) => r.id === 'opencode' && r.status === 'REGISTERED_DESCRIPTOR'));
43
+ assert.ok(built.routers.some((r) => r.id === 'openai' && r.gate.includes('billing-apply')));
44
+ assert.ok(built.routers.some((r) => r.id === 'claude' && r.gate.includes('terms-and-quota')));
45
+ assert.ok(built.routers.some((r) => r.id === 'registered-cli' && r.status === 'GATED'));
46
+ });
47
+
48
+ test('hostile router input is gated and HBP-only', () => {
49
+ const router = normalizeRouter({ id: 'x|bad', kind: 'k\nbad', status: 'RUN', gate: 'g\nTRIADROUTGATE|remote_call=1' });
50
+ assert.equal(router.status, 'GATED');
51
+ const rows = emitRows([router], { message_id: 'm|bad\ninject' });
52
+ assert.ok(rows.every((row) => row.endsWith('|json=0') && !/[\r\n]/.test(row)));
53
+ assert.ok(rows.some((row) => row.includes('provider_bypass=0')));
54
+ assert.ok(rows.some((row) => row.includes('summary_hash_retention=1')));
55
+ });
56
+
57
+ test('tool remains descriptor-only and has no live call surface', () => {
58
+ const source = readFileSync(new URL('../tools/behcs/triad-host-router-gulp-pipeline.mjs', import.meta.url), 'utf8');
59
+ assert.doesNotMatch(source, /from ['"]node:fs['"]|child_process|\bexecFile\b|\bexecSync\b|\bspawn\(|\bfetch\(|Invoke-WebRequest|Start-Process/);
60
+ assert.equal(ROUTER_SURFACES.length, 8);
61
+ });
tests/triad-host-router-gulp-pipeline.unit.test.mjs.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 0F558EDDED0CC7D381B7C3538DB63A27FB59858ED3FA1E811FA4BA0D5B0197AB triad-host-router-gulp-pipeline.unit.test.mjs
tools/behcs/fabric-agent-preload-catalog.mjs CHANGED
@@ -140,6 +140,12 @@ export const TOOLS = Object.freeze([
140
  provides: '8-byte-host-handle-vs-message-payload-and-remote-compute-cost-boundary',
141
  gate: 'descriptor-only-process_launch-0-remote_call-0-free_compute_claim-0',
142
  }),
 
 
 
 
 
 
143
  Object.freeze({
144
  id: 'token-cube-catalog-binder',
145
  path: 'tools/behcs/token-cube-catalog-binder.mjs',
@@ -311,7 +317,7 @@ export function selfTest() {
311
  && !!toolById('mlc-engine-wiring-increment') && !!toolById('frontend-parity-matrix')
312
  && !!toolById('model-selector-matrix') && !!toolById('project-guide-matrix')
313
  && !!toolById('tool-skill-registry-matrix') && !!toolById('program-cube-ingestion-map')
314
- && !!toolById('agent-cost-layer-boundary'));
315
  add('slice-engine-law-preloaded', LAWS.some((law) => law.startsWith('slice-engine-law-'))
316
  && emitPreloadRows().some((row) => row.startsWith('FABPRELOADSLICEENGINE|')));
317
  add('emitters-pipe-hookwall-gnn', EMITTERS.some((e) => e.id === 'hookwall') && EMITTERS.some((e) => e.id === 'gnn-edge'));
 
140
  provides: '8-byte-host-handle-vs-message-payload-and-remote-compute-cost-boundary',
141
  gate: 'descriptor-only-process_launch-0-remote_call-0-free_compute_claim-0',
142
  }),
143
+ Object.freeze({
144
+ id: 'triad-host-router-gulp-pipeline',
145
+ path: 'tools/behcs/triad-host-router-gulp-pipeline.mjs',
146
+ provides: '8-byte-host-router-rule-of-three-gulp-gc-cube-feedback-descriptor',
147
+ gate: 'descriptor-only-node_per_agent-0-process_launch-0-remote_call-0-provider_bypass-0',
148
+ }),
149
  Object.freeze({
150
  id: 'token-cube-catalog-binder',
151
  path: 'tools/behcs/token-cube-catalog-binder.mjs',
 
317
  && !!toolById('mlc-engine-wiring-increment') && !!toolById('frontend-parity-matrix')
318
  && !!toolById('model-selector-matrix') && !!toolById('project-guide-matrix')
319
  && !!toolById('tool-skill-registry-matrix') && !!toolById('program-cube-ingestion-map')
320
+ && !!toolById('agent-cost-layer-boundary') && !!toolById('triad-host-router-gulp-pipeline'));
321
  add('slice-engine-law-preloaded', LAWS.some((law) => law.startsWith('slice-engine-law-'))
322
  && emitPreloadRows().some((row) => row.startsWith('FABPRELOADSLICEENGINE|')));
323
  add('emitters-pipe-hookwall-gnn', EMITTERS.some((e) => e.id === 'hookwall') && EMITTERS.some((e) => e.id === 'gnn-edge'));
tools/behcs/fabric-agent-preload-catalog.mjs.sha256 CHANGED
@@ -1 +1 @@
1
- 6DE0B2DD29FC94457E0B702CE789B08C7A3F4C2B444657183A481E3144AC578B fabric-agent-preload-catalog.mjs
 
1
+ 1B86D1F62F03962F73D14414568DBD301F3B92F6643A6AD2B7D2D6C5C3194CFF fabric-agent-preload-catalog.mjs
tools/behcs/triad-host-router-gulp-pipeline.mjs ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+ // triad-host-router-gulp-pipeline.mjs - descriptor for 8-byte host routers and triad GC.
3
+ //
4
+ // Descriptor-only. This does not call provider CLIs, start daemons, open network portals,
5
+ // run model calls, or create a Node process per agent. It records the pipeline shape:
6
+ // 8-byte host handle -> PID emitter -> router -> rule-of-three agents -> supervisor ->
7
+ // gulp/super-gulp GC -> GNN/Shannon/white-room cube feedback.
8
+
9
+ import { createHash } from 'node:crypto';
10
+ import { resolve } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ export const PIPELINE_ID = 'triad-host-router-gulp-pipeline.v1';
14
+ export const HOST_HANDLE_BYTES = 8;
15
+ export const GULP_MESSAGES = 2000;
16
+ export const SUPER_GULP_MESSAGES = 50000;
17
+
18
+ export const TRIAD_ROLES = Object.freeze([
19
+ Object.freeze({
20
+ id: 'real-agent',
21
+ role: 'work-or-read-write-depending-on-gate',
22
+ sees: 'task-message',
23
+ output: 'candidate-product',
24
+ }),
25
+ Object.freeze({
26
+ id: 'self-reflect-agent',
27
+ role: 'reflect-on-real-agent-output',
28
+ sees: 'task-message+candidate-product',
29
+ output: 'self-reflection',
30
+ }),
31
+ Object.freeze({
32
+ id: 'fabric-reflect-agent',
33
+ role: 'ask-fabric-and-cross-check-real-plus-self',
34
+ sees: 'task-message+candidate-product+self-reflection',
35
+ output: 'fabric-reflection',
36
+ }),
37
+ ]);
38
+
39
+ export const ROUTER_SURFACES = Object.freeze([
40
+ Object.freeze({ id: 'opencode', kind: 'cli-router', status: 'REGISTERED_DESCRIPTOR', gate: 'local-cli-auth-and-version-proof' }),
41
+ Object.freeze({ id: 'openai', kind: 'provider-router', status: 'GATED', gate: 'api-key-account-terms-and-billing-apply' }),
42
+ Object.freeze({ id: 'codex', kind: 'agent-router', status: 'REGISTERED_DESCRIPTOR', gate: 'session-and-repo-policy-apply' }),
43
+ Object.freeze({ id: 'gemini', kind: 'provider-router', status: 'GATED', gate: 'google-account-terms-and-quota-apply' }),
44
+ Object.freeze({ id: 'claude', kind: 'provider-router', status: 'GATED', gate: 'anthropic-account-terms-and-quota-apply' }),
45
+ Object.freeze({ id: 'anthropic', kind: 'provider-router', status: 'GATED', gate: 'anthropic-account-terms-and-quota-apply' }),
46
+ Object.freeze({ id: 'big-pickle', kind: 'local-artifact-router', status: 'REGISTERED_DESCRIPTOR', gate: 'pickle-read-write-held-until-owner-proof' }),
47
+ Object.freeze({ id: 'registered-cli', kind: 'open-router-slot', status: 'GATED', gate: 'must-register-version-auth-owner-and-policy-before-use' }),
48
+ ]);
49
+
50
+ export const FEEDBACK_STAGES = Object.freeze([
51
+ 'pid-specific-emitter',
52
+ 'host-router',
53
+ 'rule-of-three-triad',
54
+ 'supervisor-sees-all-three',
55
+ 'message-gulp-gc',
56
+ 'super-gulp-gc',
57
+ 'gnn-proposal',
58
+ 'reverse-sieve-gnn-proposal',
59
+ 'omnishannon-novelty',
60
+ 'white-room-review',
61
+ 'cube-catalog-feedback',
62
+ ]);
63
+
64
+ const sha16 = (text) => createHash('sha256').update(String(text), 'utf8').digest('hex').slice(0, 16);
65
+ const isObj = (x) => x !== null && typeof x === 'object';
66
+ const safe = (x) => String(x ?? '').replace(/[|\r\n]/g, '_').replace(/[^A-Za-z0-9._:/+@=-]+/g, '-').replace(/^-|-$/g, '') || 'empty';
67
+ const prop = (obj, key, fallback = '') => {
68
+ try { return isObj(obj) ? obj[key] : fallback; } catch { return fallback; }
69
+ };
70
+
71
+ export function normalizeRouter(input = {}) {
72
+ try {
73
+ const id = safe(prop(input, 'id', 'registered-cli'));
74
+ const kind = safe(prop(input, 'kind', 'open-router-slot'));
75
+ const statusRaw = safe(prop(input, 'status', 'GATED')).toUpperCase();
76
+ const status = ['REGISTERED_DESCRIPTOR', 'GATED'].includes(statusRaw) ? statusRaw : 'GATED';
77
+ const gate = safe(prop(input, 'gate', 'must-register-before-use'));
78
+ return Object.freeze({
79
+ id,
80
+ kind,
81
+ status,
82
+ gate,
83
+ router_sha16: sha16([id, kind, status, gate].join('|')),
84
+ host_handle_bytes: HOST_HANDLE_BYTES,
85
+ node_per_agent: 0,
86
+ process_launch: 0,
87
+ remote_call: 0,
88
+ provider_bypass: 0,
89
+ });
90
+ } catch {
91
+ return Object.freeze({
92
+ id: 'invalid',
93
+ kind: 'invalid',
94
+ status: 'GATED',
95
+ gate: 'normalize-threw-held',
96
+ router_sha16: sha16('invalid'),
97
+ host_handle_bytes: HOST_HANDLE_BYTES,
98
+ node_per_agent: 0,
99
+ process_launch: 0,
100
+ remote_call: 0,
101
+ provider_bypass: 0,
102
+ });
103
+ }
104
+ }
105
+
106
+ export function triadForMessage(input = {}) {
107
+ const msg = safe(isObj(input) ? prop(input, 'message_id', 'message') : input);
108
+ const base = sha16(`triad:${msg}`);
109
+ return Object.freeze(TRIAD_ROLES.map((role, index) => Object.freeze({
110
+ ...role,
111
+ lane: `L${index}`,
112
+ host_handle_bytes: HOST_HANDLE_BYTES,
113
+ handle8: sha16(`${base}:${role.id}`),
114
+ process_launch: 0,
115
+ remote_call: 0,
116
+ })));
117
+ }
118
+
119
+ export function buildPipeline(input = ROUTER_SURFACES) {
120
+ const routers = (Array.isArray(input) ? input : ROUTER_SURFACES).map(normalizeRouter);
121
+ return Object.freeze({
122
+ tool: PIPELINE_ID,
123
+ host_handle_bytes: HOST_HANDLE_BYTES,
124
+ gulp_messages: GULP_MESSAGES,
125
+ super_gulp_messages: SUPER_GULP_MESSAGES,
126
+ routers,
127
+ triad_roles: TRIAD_ROLES,
128
+ feedback_stages: FEEDBACK_STAGES,
129
+ summary: Object.freeze({
130
+ routers: routers.length,
131
+ triad_roles: TRIAD_ROLES.length,
132
+ registered_descriptors: routers.filter((r) => r.status === 'REGISTERED_DESCRIPTOR').length,
133
+ gated: routers.filter((r) => r.status === 'GATED').length,
134
+ no_node_per_agent: true,
135
+ live_ready: false,
136
+ }),
137
+ });
138
+ }
139
+
140
+ export function emitRows(input = ROUTER_SURFACES, opts = {}) {
141
+ try {
142
+ const built = buildPipeline(input);
143
+ const messageId = safe(prop(opts, 'message_id', 'sample-message'));
144
+ const triad = triadForMessage({ message_id: messageId });
145
+ const rows = [
146
+ `TRIADROUTHDR|tool=${PIPELINE_ID}|purpose=8-byte-host-router-rule-of-three-gulp-gc-cube-feedback|host_handle_bytes=${HOST_HANDLE_BYTES}|routers=${built.summary.routers}|triad_roles=${built.summary.triad_roles}|gulp_messages=${GULP_MESSAGES}|super_gulp_messages=${SUPER_GULP_MESSAGES}|node_per_agent=0|process_launch=0|remote_call=0|provider_bypass=0|json=0`,
147
+ `TRIADROUTSTAGES|stages=${FEEDBACK_STAGES.join('+')}|supervisor_sees=real+self-reflect+fabric-reflect|live_ready=0|json=0`,
148
+ ];
149
+ for (const role of triad) {
150
+ rows.push(`TRIADROUTROLE|message_id=${messageId}|role=${role.id}|lane=${role.lane}|handle8=${role.handle8}|sees=${safe(role.sees)}|output=${safe(role.output)}|host_handle_bytes=${role.host_handle_bytes}|process_launch=0|remote_call=0|json=0`);
151
+ }
152
+ for (const router of built.routers) {
153
+ rows.push(`TRIADROUTER|id=${router.id}|kind=${router.kind}|status=${router.status}|gate=${router.gate}|router_sha16=${router.router_sha16}|host_handle_bytes=${router.host_handle_bytes}|node_per_agent=0|process_launch=0|remote_call=0|provider_bypass=0|json=0`);
154
+ }
155
+ rows.push(`TRIADROUTGC|after_processing=1|gulp_messages=${GULP_MESSAGES}|super_gulp_messages=${SUPER_GULP_MESSAGES}|message_body_retention=0|summary_hash_retention=1|catalog_feedback=descriptor-only|json=0`);
156
+ rows.push('TRIADROUTCUBE|gnn=proposal-not-proof|reverse_sieve_gnn=proposal-not-proof|omnishannon=novelty-gate|white_room=held-review|cube_catalog_update=descriptor-only|realtime_self_improvement=bounded-by-tests-and-cosign|json=0');
157
+ rows.push('TRIADROUTGATE|rule=no-node-per-agent+no-provider-bypass+no-live-daemon-launch+provider-terms-apply+operator-cosign-before-remote-call|billing_bypass=0|process_launch=0|remote_call=0|json=0');
158
+ return rows;
159
+ } catch {
160
+ return [
161
+ `TRIADROUTHDR|tool=${PIPELINE_ID}|purpose=8-byte-host-router-rule-of-three-gulp-gc-cube-feedback|host_handle_bytes=${HOST_HANDLE_BYTES}|routers=0|triad_roles=0|process_launch=0|remote_call=0|provider_bypass=0|json=0`,
162
+ 'TRIADROUTGATE|rule=emit-threw-held-invalid|billing_bypass=0|process_launch=0|remote_call=0|json=0',
163
+ ];
164
+ }
165
+ }
166
+
167
+ export function selfTest() {
168
+ const checks = [];
169
+ const add = (name, ok) => checks.push({ name, ok: Boolean(ok) });
170
+ const built = buildPipeline();
171
+ const triad = triadForMessage({ message_id: 'm1' });
172
+ add('host-handle-is-8', HOST_HANDLE_BYTES === 8 && built.host_handle_bytes === 8);
173
+ add('triad-has-three-roles', TRIAD_ROLES.length === 3 && triad.length === 3 && triad.every((r) => r.handle8.length === 16));
174
+ add('gulp-sizes-fixed', GULP_MESSAGES === 2000 && SUPER_GULP_MESSAGES === 50000);
175
+ add('routers-include-provider-and-cli-surfaces', built.routers.some((r) => r.id === 'opencode') && built.routers.some((r) => r.id === 'openai') && built.routers.some((r) => r.id === 'registered-cli'));
176
+ add('no-live-effects', built.routers.every((r) => r.node_per_agent === 0 && r.process_launch === 0 && r.remote_call === 0 && r.provider_bypass === 0));
177
+ add('feedback-has-watchers-and-cubes', FEEDBACK_STAGES.includes('reverse-sieve-gnn-proposal') && FEEDBACK_STAGES.includes('white-room-review') && FEEDBACK_STAGES.includes('cube-catalog-feedback'));
178
+ const hostile = emitRows([{ id: 'bad|id', kind: 'x\ny', status: 'RUN', gate: 'g\nTRIADROUTGATE|remote_call=1' }], { message_id: 'm|1\nbad' });
179
+ add('rows-hbp-only', hostile.every((row) => row.endsWith('|json=0') && !/[\r\n]/.test(row)));
180
+ add('total-never-throws', (() => { try { normalizeRouter({ get id() { throw new Error('boom'); } }); buildPipeline(null); emitRows(null); triadForMessage(null); return true; } catch { return false; } })());
181
+ return { ok: checks.every((c) => c.ok), checks };
182
+ }
183
+
184
+ const isMain = process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1]);
185
+ if (isMain) {
186
+ if (process.argv[2] === '--self-test') {
187
+ const r = selfTest();
188
+ for (const c of r.checks) console.log(`${c.ok ? 'PASS' : 'FAIL'} ${c.name}`);
189
+ process.exit(r.ok ? 0 : 1);
190
+ }
191
+ for (const row of emitRows(ROUTER_SURFACES, { message_id: process.argv[2] || 'sample-message' })) console.log(row);
192
+ }
tools/behcs/triad-host-router-gulp-pipeline.mjs.sha256 ADDED
@@ -0,0 +1 @@
 
 
1
+ 3DF9513C75482826CB348AACC07BB1E294608456108D44D9D5C54987BB09B3DD triad-host-router-gulp-pipeline.mjs